无法分配具有已删除复制构造函数的引用?

Cannot assign a reference that has a deleted copy constructor?

提问人:yano 提问时间:9/22/2021 更新时间:9/22/2021 访问量:737

问:

我处于需要为一个类实现 Move 构造函数和 Move-Assignment 运算符的情况,该类包含对具有已删除的 Copy Ctor 和 Copy-Assignment 运算符的对象的引用,基本上如下所示:

class MoveOnlyThing
{
public:
    MoveOnlyThing() = default;
    MoveOnlyThing(const MoveOnlyThing&) = delete;
    MoveOnlyThing& operator=(const MoveOnlyThing&) = delete;
};

class Holder
{
public:
    Holder(MoveOnlyThing& t)
    : mThing(t)
    {
    }
    
    Holder(Holder&& other)
    : mThing(other.mThing)
    {
    }
    
    Holder& operator=(Holder&& other)
    {
        mThing = other.mThing;
        return *this;
    }
    
    MoveOnlyThing& mThing;
};

现在,问题是,赋值发出错误:mThing = other.mThing;

main.cpp:40:16: error: overload resolution selected deleted operator '='
        mThing = other.mThing;
        ~~~~~~ ^ ~~~~~~~~~~~~
main.cpp:20:12: note: candidate function has been explicitly deleted
    MoveOnlyThing& operator=(const MoveOnlyThing&) = delete;
           ^

提出了两个问题;

  1. 我们该如何处理这个问题?实现 Move 构造函数,然后使用它来实现 Move-Assignment 运算符?
  2. 我没有意识到在这种情况下,编译器会在重新分配现有引用时生成副本。谁能解释呢?
C++ 参考 C++17 复制构造函数 move-assignment-operator

评论

4赞 user4581301 9/22/2021
无法指定引用。仅初始化。
4赞 Ben Voigt 9/22/2021
你误解了 的意思。它不是意味着“为引用分配一个新值”,而是意味着“为(指向的对象)分配一个新值”。引用以隐式方式间接执行,每当使用引用的名称时,您实际上都会获得它所指向的对象mThing = other.mThing;mThingmThing
1赞 yano 9/22/2021
@BenVoigt是的,这是正确的,所以实际上它尝试调用复制构造函数的原因是为了分配给原始对象,感谢您指出这一点
0赞 Remy Lebeau 9/22/2021
为了调用 的 move assignment 运算符,您需要:std::move()MoveOnlyThingmThing = std::move(other.mThing);

答: 暂无答案