使用 swap 实现移动赋值

using swap to implement move assignment

我想到了一些我认为完全合理的事情,但我希望人们对此发表意见,以防我完全遗漏某些东西。所以首先,我对 T& operator=(T&& rhs) 的理解是我们 不关心 当我们完成后 rhs 的内容是什么,只是内容已被移动进入 this 并且 rhs 是可安全破坏的。

也就是说,复制赋值运算符的常见异常安全实现,假设交换很便宜,看起来像这样:

T& operator=(const T& rhs) {
    if(this != &rhs) {
        T(rhs).swap(*this);
    }
    return *this;
}

因此,实现移动赋值运算符的一种自然方式如下:

T& operator=(T&& rhs) {
    if(this != &rhs) {
        T(std::move(rhs)).swap(*this);
    }
    return *this;
}

但后来我想到,rhs 不一定是空的!那么,为什么不直接做一个简单的 swap?

T& operator=(T&& rhs) {
    rhs.swap(*this); // is this good enough?
    return *this;
}

认为这满足了移动赋值运算符需要做的...但是就像我说的,这只是我想到的,所以我认为有可能我错过了一些东西。

我唯一能想到的 "downside" 是 this 拥有的东西与使用 move-construct/swap 的版本相比,使用普通交换可能会活得更久。

想法?

"what the move-assignment operator needs to do"

我总是发现处理 && 变量的最佳方法是说 "nobody cares what state I leave this variable in"。你可以离开它。您可以从中复制。您可以换成它。您可以做更多的事情。

您的代码是正确的。 && 可以保持任何状态(只要它是可破坏的)。

对象迟早会被销毁(可能更早),实现者应该意识到这一点。如果析构函数将 delete 原始指针,这很重要,如果同一个原始指针在多个对象中,这将导致双重删除。