如何使用右值调用复制构造函数
How copy constructor can be called with 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
fora2
使用了复制省略,这是对编译器的优化,一切似乎都很好。但是,当我注释掉移动构造函数时,将调用复制构造函数来代替移动构造函数。如何将右值转换为 const 左值引用?
输出:
constructor
copy constructor
constructor
copy constructor
程序编译于VS2017
。
来自en.cppreference.com:
If both copy and move constructors are provided and no other
constructors are viable, overload resolution selects the move
constructor if the argument is an rvalue of the same type (an xvalue
such as the result of std::move or a prvalue such as a nameless
temporary (until C++17)), and selects the copy constructor if the
argument is an lvalue (named object or a function/operator returning
lvalue reference). If only the copy constructor is provided, all
argument categories select it (as long as it takes a reference to
const, since rvalues can bind to const references), which makes
copying the fallback for moving, when moving is unavailable.
这清楚地表明右值可以绑定到 const 左值引用。
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
fora2
使用了复制省略,这是对编译器的优化,一切似乎都很好。但是,当我注释掉移动构造函数时,将调用复制构造函数来代替移动构造函数。如何将右值转换为 const 左值引用?
输出:
constructor
copy constructor
constructor
copy constructor
程序编译于VS2017
。
来自en.cppreference.com:
If both copy and move constructors are provided and no other constructors are viable, overload resolution selects the move constructor if the argument is an rvalue of the same type (an xvalue such as the result of std::move or a prvalue such as a nameless temporary (until C++17)), and selects the copy constructor if the argument is an lvalue (named object or a function/operator returning lvalue reference). If only the copy constructor is provided, all argument categories select it (as long as it takes a reference to const, since rvalues can bind to const references), which makes copying the fallback for moving, when moving is unavailable.
这清楚地表明右值可以绑定到 const 左值引用。