Как конструктор копирования может быть вызван с помощью rvalue
MWE:
struct A {
A() {std::cout << "constructor" << std::endl; }
A(const A& a) {std::cout << "copy constructor" << std::endl; }
A(A&& a) {std::cout << "move constructor" << std::endl; }
};
int main() {
A a1{};
A a2{ a1 };
A a3{ A{} };
A a4{ std::move(a3) };
return 0;
}
Выход:
constructor
copy constructor
constructor
move constructor
заa2
Копирование elision используется, что является оптимизацией компилятора, и все вроде бы хорошо. Однако, когда я закомментирую конструктор перемещения, вместо конструктора перемещения вызывается конструктор копирования. Как можно преобразовать rvalue в ссылку const lvalue? Выход:
constructor
copy constructor
constructor
copy constructor
Программа составлена в VS2017
,
1 ответ
От en.cppreference.com:
Если предусмотрены конструкторы копирования и перемещения, а другие конструкторы не являются жизнеспособными, разрешение перегрузки выбирает конструктор перемещения, если аргумент является значением r того же типа (значением x, например, результатом std::move, или значением prvalue, например, безымянным. временный (до C++17)) и выбирает конструктор копирования, если аргумент является lvalue (именованный объект или функция / оператор, возвращающий ссылку на lvalue). Если предоставляется только конструктор копирования, все категории аргументов выбирают его (при условии, что он принимает ссылку на const, поскольку rvalues может связываться с ссылками на const), что делает копирование запасного варианта для перемещения, когда перемещение недоступно.
Это ясно говорит о том, что rvalue может быть связано с константой lvalue.