为啥移动赋值运算符应该返回对 *this 的引用 [重复]

Posted

技术标签:

【中文标题】为啥移动赋值运算符应该返回对 *this 的引用 [重复]【英文标题】:Why move assignment operator should return reference to *this [duplicate]为什么移动赋值运算符应该返回对 *this 的引用 [重复] 【发布时间】:2015-05-31 06:12:57 【问题描述】:

有人可以解释为什么移动赋值运算符(通常)被声明为

Foo& operator=(Foo&&);

为什么返回引用而不是例如Foo 还是 Foo&&?我理解为什么我们希望常规赋值运算符使用这个,因为(a=b)=c 的关联规则在逻辑上被破坏(尽管仍然可编译)如果不是通过引用返回,但是为什么当 RHS 是右值(xvalue/prvalue)时会出现这种情况)?

【问题讨论】:

完全不清楚你在问什么。除非通过引用,否则您不能返回“对象本身”。如果您的意思是“为什么不返回对象的副本”,那么只有在类型是可复制的情况下才有效,即使这样复制也可能比您想要的更昂贵。 (a=b)=c 要求第一个表达式 (a=b) 是一个 lvalue 无论赋值运算符的参数类型如何,因此如果你想支持它,你必须返回一个引用。 @MikeSeymour 我改变了问题,为什么不直接返回Foo?甚至Foo&&?哪些“链式”规则将被打破? 返回 Foo 可能很昂贵,如果类型不可复制,则不可能,正如我所说。返回Foo&& 很奇怪;你不希望事情神秘地变成 rvalues 以便例如f(a=b) 出人意料地从 a 移动,而你没有告诉它。 @MikeSeymour 谢谢,这一点很好,你应该发布(如果你想)一个答案,因为我认为这个问题不是很明显,尽管现在它很有意义。 另一种看待它的方式。如果你想要的只是一个右值并且你可以做一个复制,你总是可以做Foo&& x = Foo(y);这在我看来与 y 上的移动操作符相同,所以在这种情况下移动操作符将是多余的在复制构造函数之上。 【参考方案1】:

返回 Foo 可能很昂贵,如果类型不可复制,则不可能。这也令人惊讶:(a=b)=c 会创建一个临时并将 c 分配给它,而您希望两个分配都分配给 a

返回Foo&& 很奇怪;你不希望事情神秘地变成 rvalues 以便例如f(a=b) 出人意料地从 a 移动,而您没有告诉它。

返回Foo& 是常规方式,如果您将其链接起来,则操作员的行为方式并不令人惊讶。

【讨论】:

以上是关于为啥移动赋值运算符应该返回对 *this 的引用 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

c++中为啥赋值运算符重载返回类型是引用

为啥我们在赋值运算符重载中使用引用返回而不是在加减运算中?

c++重载赋值操作符的返回值是啥?

C++ 为啥赋值运算符应该返回一个 const ref 以避免 (a=b)=c

C++中的重载赋值运算符

c++中重载输出操作符,为啥要返回引用