考虑下面的移动赋值运算符:
class MyClass {
private:
ssize_t buf_size;
void* buf_ptr;
public:
MyClass &operator=(MyClass &&rhs) {
if (this != &rhs) {
buf_size = rhs.buf_size;
buf_ptr = rhs.buf_ptr;
rhs.buf_ptr = nullptr;
rhs.buf_size = -1;
}
return *this;
}
}
是什么阻止我们使用
&operator=(MyClass &&rhs)
而不是 &operator=(MyClass &rhs)
作为方法的签名?据我了解,如果 rhs
是左值,则所有对 rhs
的引用都应该有效。
我可以看到一个问题:使用
&operator=(MyClass &rhs)
使复制赋值运算符和移动赋值运算符看起来相同,并且我们无法识别要调用哪个运算符。但还有更深层次的原因吗?
右值引用没有比与左值引用不同的“更深层的原因”。自动确定引用是对左值还是右值,并执行正确的代码作为响应,这是它们存在的全部原因。例如,
myClass = MyClass{}
不适用于采用左值引用的函数,因为临时变量不是左值。