copy and swap技巧与移动赋值操作符

最近在实现一个Delegate类的时候碰到了一个问题,就是copy and swap技巧和移动赋值操作符有冲突。
比如有以下一个类:

class Fun
{
public:
    Fun(const Fun& rhs) throw();

    Fun& operator=(Fun fun)
    {
        swap(fun);
        return *this;
    }

    void swap(Fun& other) throw();
};

这个类实现了copy and swap技巧,在赋值的时候表现的很好。但是如果再加入移动赋值操作符,编译器就不认了:

class Fun
{
    //...
    Fun& operator=(Fun fun)
    {
        swap(fun);
        return *this;
    }

    Fun& operator=(Fun&& fun)
    {
        swap(fun);
        return *this;
    }
    //...
};

Fun f;
f = Fun();  //报错

当你调用赋值操作符时,编译器会提示有两个赋值操作符,不知道该调用哪一个!
移动赋值操作符的引入就是为了优化用右值赋值的情况,而copy and swap本身就运用了处理右值情况的技巧,所以在这里会出现冲突。因此如果使用了copy and swap技巧,那么移动赋值操作符就可以省略了,下面是copy and swap技巧的C++11写法:

class Fun
{
public:
    Fun(const Fun& rhs) throw();

    Fun(Fun&& rhs) throw()
        //记得数据初始化
    {
        swap(rhs);
    }

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

    void swap(Fun& other) throw();
};

不过如果数据结构比较复杂,不适合用copy and swap技巧,那么就需要显式的定义左值赋值操作符和右值赋值操作符了:

class Fun
{
    //...
    Fun& operator=(const Fun& fun); //左值赋值操作符
    Fun& operator=(Fun&& fun);      //右值赋值操作符
    //...
};

参考文献:http://stackoverflow.com/questions/19841626/move-assignment-incompatable-with-standard-copy-and-swap

猜你喜欢

转载自blog.csdn.net/vvsxr/article/details/51058664
今日推荐