赋值运算符的返回类型

18

当定义一个赋值操作符时,通常看起来像这样:

class X {...};

X& X::operator=(...whatever...);

也就是说,它的返回类型是“X的引用”。在这里,参数(...whatever...)可以是X&const X&,使用拷贝-交换惯用法时仅为X,或任何其他类型。

奇怪的是,所有人都推荐返回非const引用,而不管参数如何。这明确允许像(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(如果这很重要的话)。


同意,我一开始就错过了。 - billz
1
在C++中有一个总体建议:重载运算符应该与整数的行为类似。整数可以进行链式操作(a = b = c = 3),因此在重载时应该保留这种语法可能性。 - Matthieu M.
@MatthieuM。+1。当然,像流上的<<这样的好规则也有更好的例外。 - Angew is no longer proud of SO
2
@Angew:实际上,这可能有点奇怪,因为我从来没有真正做过C语言,所以对我来说<<主要是一个流操作符,而某些奇怪的人决定将其用于位移 :) - Matthieu M.
3
无论你认为用户的编码风格有多糟糕,都不应该无谓地限制它。想象一下,如果用户创建了一个模板函数并尝试使用你的类,如果你的操作符不再按预期工作,那么代码可能无法通过编译。 - Neil Kirk
1个回答

27

您的类不符合CopyAssignable概念(§17.6.3.1),因此不能保证与要求此特性的标准容器一起使用(例如,std::vectorinsert操作中需要此特性)。

此外,这种行为不符合惯用法,并且会让使用您代码的程序员感到惊讶。如果您想禁止链式赋值,请考虑添加一个命名函数来执行赋值操作。

但是,请不要试图以微妙的方式更改惯用运算符的行为,这将使您的代码更难阅读和维护。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接