5

这些是我的原型,

MyClass& operator=(MyClass rhs);   // copy assignment
MyClass& operator=(MyClass &&rhs); // move assignment

但是当我打电话

MyClass a, b;
a = std::move(b);

, 有错误。

556 IntelliSense: more than one operator "=" matches these operands:
        function "MyClass::operator=(MyClass rhs)"
        function "MyClass::operator=(MyClass &&rhs)"
        operand types are: MyClass = MyClass    

编译器返回:

Error   56  error C2593: 'operator =' is ambiguous  
4

1 回答 1

11

重载决议是模棱两可的,因为当你传递一个右值时,两者MyClassMyClass &&可以直接由它初始化。

如果你想提供不同的复制和移动赋值实现,通常的方法是通过 const 引用获取复制赋值运算符的参数:

MyClass& operator=(const MyClass &rhs);   // copy assignment
MyClass& operator=(MyClass &&rhs); // move assignment

像这样完成后,移动赋值运算符是(非常量)右值参数的严格匹配,因此它是由重载决议选择的。

另一种称为复制和交换的方法是只提供赋值运算符,按值获取参数,并使用swap它来实现它:

MyClass& operator=(MyClass rhs)
{
  swap(*this, rhs);
  return *this;
};

这重用了分配的复制/移动构造函数。它要求您已经实现了一个swap功能,该功能应该是非抛出的。

这种方法的缺点是,有时手动实现复制分配可能比执行复制构造然后移动便宜。

于 2015-04-17T12:29:19.240 回答