如何删除移动赋值运算符并保​​持与标准容器的兼容性?

How to delete the move assignment operator and retain compatibility with std containers?

我有一个用于管理特定资源的简单 RAII 包装器。这是界面:

struct ResourceWrapper
{
    explicit ResourceWrapper(RESOURCE resource);
    ResourceWrapper(const ResourceWrapper& other);
    ResourceWrapper& operator=(const ResourceWrapper& other);
    ~ResourceWrapper();

    ResourceWrapper(ResourceWrapper&& other) = delete;
    ResourceWrapper& operator=(ResourceWrapper&& other) = delete;
};

这里的问题是,一旦我明确删除移动赋值运算符,我就无法再将此 class 与 std 容器和算法一起使用。显然我确实需要删除或正确实现它,因为我刚刚学到了很多东西。

另一种选择是通过常规赋值运算符实现移动赋值,但我不确定如何正确地做到这一点。我想我需要像 std::remove_reference 这样的东西?我想知道它是否会删除太多引用并导致创建不必要的临时对象。

And obviously I do need to either delete or properly implement it, as I've just learned the hard way.

不,你不知道。

您的 class 具有 user-defined 复制构造函数、复制赋值运算符和析构函数,因此编译器将 不会 为您定义移动赋值运算符。

所以停止尝试删除它,class 将被复制而不是移动。

使用 deleted 移动操作,您无法复制类型的右值,即它变得非常难以用作值类型(包括在容器中)。使用 no 移动操作,它只会做右值的深拷贝,这是安全的,可能是你想要的。

仅当您希望 class 完全是 un-movable 和 un-copyable 时,删除移动操作才有意义,例如类似于互斥锁类型,其中对象标识至关重要,而不是它的值。删除移动的可复制类型永远没有意义。