引用具有禁用副本的对象 constructor/assignment

Reference to an object with disabled copy constructor/assignment

在我的应用程序中,我有一个对象列表。因为我必须只有一个实例,所以我禁用了复制构造函数和赋值运算符。仍然允许移动对象。但是由于我对对象执行了各种操作,所以我需要存储指向其中一个对象的指针。在我为此目的使用指针之前,但我现在想使用一个引用。

出于某种原因,我无法重新分配引用。错误:

error: overload resolution selected deleted operator '='
candidate function has been explicitly deleted

演示该问题的示例代码:

#include <iostream>

class Item
{
public:
    Item() { n = (++Item::counter); }
    Item(const Item&& other) { n = std::move(other.n); }
    Item(const Item& other) = delete;
    Item& operator=(const Item& other) = delete;
    int Get() { return n; }
private:
    int n;
    static int counter;
};

int Item::counter = 0;

int main()
{
    Item i1;
    Item i2;

    Item *p = &i1;
    printf("%d\n", p->Get());

    p = &i2;
    printf("%d\n", p->Get());

    Item &r = i1;
    printf("%d\n", r.Get());

    r = i2; // here I get the error
    printf("%d\n", r.Get());

    return 0;
}

好的,如果我在这样的事情上出错,我可以理解:

Item i3 = i2;

即如果真的有任务。但是这里我只是想存储对象的引用,而不是将其分配或复制到另一个对象。

所以我的问题是如何存储对非复制对象的引用以避免指针?

在 C++ 中,引用不可重新绑定。这是什么意思?这意味着一旦创建了引用,就不能更改该引用所引用的对象。它具有重大意义 - 例如此代码:

Item i1;
Item i2;
Item &r = i1;
r = i2; 

在逻辑上等同于这个:

Item i1;
Item i2;
i1 = i2; 

现在应该明白为什么编译器的赋值运算符有问题了。什么是要做?您可以使用 std::reference_wrapper 这就是您想要的 - 可重新绑定的引用类型:

Item i1;
Item i2;
auto r = std::ref(i1);
r = std::ref(i2);