【发布时间】:2021-11-15 09:16:45
【问题描述】:
我的情况是,我需要为一个类实现移动构造函数和移动赋值运算符,该类包含对具有已删除复制因子和复制分配运算符的对象的引用,基本上如下所示:
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;
^
提出了两个问题;
- 我们如何处理这个问题?实现 Move Constructor,然后用它来实现 Move-Assignment Operator?
- 我没有意识到在这种情况下编译器会在重新分配现有引用时生成一个副本。谁能解释一下?
【问题讨论】:
-
您无法指定参考。仅初始化。
-
你误解了
mThing = other.mThing;的意思。这并不意味着“为引用mThing分配一个新值”,而是“为(mThing指向的对象)分配一个新值”。引用隐式执行间接,任何时候您使用引用的名称,您实际上都会得到它所指向的对象。 -
@BenVoigt 是的,这是正确的,所以实际上它尝试调用复制构造函数的原因是分配给 原始对象 感谢您指出这一点
-
您需要
std::move()才能调用MoveOnlyThing的移动赋值运算符:mThing = std::move(other.mThing);
标签: c++ reference c++17 copy-constructor move-assignment-operator