如果我定义了一个复制赋值运算符,该复制赋值运算符使用thing类的按值传递来调用复制构造函数:

thing& operator= (thing x) {

和同一个类(class)的 move 分配运算符:
thing& operator= (thing&& x) {

尝试调用 move 分配会导致来自gcc的错误:
error: ambiguous overload for ‘operator=’ (operand types are ‘thing’ and ‘std::remove_reference<thing&>::type {aka thing}’)

但是,如果拷贝分配改为使用按引用传递:
thing& operator= (thing& x) {

编译很好,并且两个运算符都可以被调用。为什么是这样?

完整的C++ 11测试代码:
#include <iostream>
#include <utility>

using namespace std;

class thing {
    public:
        thing () { }
        thing (thing& x) {
            cout << "Copy constructor.\n";
        }
        thing (thing&& x) {
            cout << "Move constructor.\n";
        }
        thing& operator= (thing x) {
            cout << "Copy assign using pass by value.\n";
            return *this;
        }
        thing& operator= (thing&& x) {
            cout << "Move assign.\n";
            return *this;
        }
};


int main (void) {
    thing a, b;
// Invoke move assignment:
    a = move(b);
    return 0;
}

最佳答案

  • 调用move(b)返回一个rvalue
  • operator=(thing &&x)operator=(thing x)都可以接受rvalues作为输入。
  • 这样,两个重载是模棱两可的,编译器理所当然地提示,因为它无法在它们之间进行选择。
  • 关于c++ - 使用 move 分配和按值复制分配传递给operator =的模棱两可的重载,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24435500/

    10-16 19:33