操作符的模糊重载=使用移动分配和传递值复制分配

时间:2014-06-26 16:14:03

标签: c++ g++ move-semantics

如果我定义了一个复制赋值运算符,它使用类thing的pass by值调用复制构造函数:

thing& operator= (thing x) {

和同一类的移动赋值运算符:

thing& operator= (thing&& x) {

尝试调用移动分配会导致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;
}                        

1 个答案:

答案 0 :(得分:3)

  • 致电move(b)会返回rvalue

  • operator=(thing &&x)operator=(thing x)都可以接受rvalues作为输入。

  • 因此,两个重载是不明确的,编译器正确地抱怨,因为它不能在它们之间做出选择。