赋值运算符的返回类型
Posted
技术标签:
【中文标题】赋值运算符的返回类型【英文标题】:Return type of assignment operator 【发布时间】:2021-10-28 07:54:50 【问题描述】:在定义赋值运算符时,它总是如下所示:
class X ...;
X& X::operator=(...whatever...);
也就是说,它的返回类型是“对 X 的引用”。在这里,参数(...whatever...
)可以是X&
,const X&
,当使用copy-and-swap idiom时,可以是X
,或者任何其他类型。
不管参数如何,everyone recommends returning a non-const reference to X
似乎很奇怪。这明确允许像(a = b).clear()
这样的表达式,这应该是好的。
我有不同的看法,我想在我的代码中禁止(x=y).clear
、(x=y)=z
甚至x=y=z
之类的表达式。我的想法是这些表达式在一行代码中做的事情太复杂了。所以我决定让我的赋值运算符返回void
:
void X::operator=(X) ...
void X::operator=(int) ...
这有什么负面影响? (除了看起来和平时不一样)
我的 X 类可以与标准容器一起使用吗(例如 std::vector<X>
)?
我正在使用 C++03(如果重要的话)。
【问题讨论】:
同意,我从一开始就错过了。 在 C++ 中有一个总体建议:重载运算符的行为应该与它们在整数上的行为相似。可以在整数 (a = b = c = 3
) 上进行链接,因此在重载时应该保留这种语法可能性。
@MatthieuM。 +1。当然,与往常一样,好的规则有更好的例外:<<
on stream 浮现在脑海中。
@Angew:实际上,这可能很奇怪,因为我从来没有真正做过 C,因此对我来说 <<
主要是一个流操作符,碰巧一些奇怪的家伙决定将它用于位移:)
你不应该不必要地限制你的用户的编码风格,不管你认为它有多糟糕。考虑他们制作模板功能,并尝试使用您的类。如果您的运算符不再按预期方式工作,它可能不再编译。
【参考方案1】:
您的类不符合 CopyAssignable 概念(第 17.6.3.1 节),因此标准不再保证可以使用需要此功能的标准容器(例如,std::vector
要求 insert
操作使用此功能) .
除此之外,这种行为不是惯用的,使用您的代码的程序员会感到惊讶。如果您想禁止链接,请考虑添加一个命名函数来执行分配。
只是不要试图以这种微妙的方式改变惯用运算符的行为。它会使您的代码更难阅读和维护。
【讨论】:
以上是关于赋值运算符的返回类型的主要内容,如果未能解决你的问题,请参考以下文章