我这样定义一个类A
:
class A {
public:
A(){
cout << "A constructing..." << endl;
}
A(const A &a){
cout << "A copy constructing..." << endl;
}
A(A&& a){
strcpy(name, a.name);
cout << "A move constructing..." << endl;
}
~A(){
cout << "A destructing..." << name << endl;
}
};
一个简单的功能:
A f(A&& b) {
cout << "------after call------" << endl;
A f = b; // Use "A f(b)" to get the same effect
cout << "------before return------" << endl;
return f;
}
当我调用auto test = f(move(b));
时,为什么要调用拷贝构造函数而不是move构造函数? b
中的f()
不是右值吗?
答案 0 :(得分:1)
不,b
主体中的表达式f
是一个左值。即使变量的声明具有右值引用类型,变量的名称也始终是左值。
该规则之所以存在,是因为否则,在您想要的时候意外地将其从变量中移走会有些容易:
void validate(A obj);
void f(A&& b) {
A a1 = b;
// Maybe some other code in between.
A a2 = b;
}
即使某些A
右值表达式已传递给f
,但一旦在f
中,它就有一个名称,因此该对象可以多次使用。如果我们复制而不是两次都移动,那么至少比移动安全,然后尝试使用moved-from变量。
因此,当您知道这是最后一次需要该变量的值时,请在右值引用变量名称上使用std::move
,以明确告知上下文可以移动。