问题描述
在我的应用程序中,我有一个对象列表。由于我必须只有一个实例,因此我禁用了复制构造函数和赋值运算符。仍然允许移动对象。但是,由于我对对象执行了各种操作,因此需要存储指向其中一个的指针。在我将指针用于此目的之前,但现在我想使用一个引用。
由于某些原因,我无法重新分配参考。错误:
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);