C++中运算符的返回类型是什么?

6

我正在阅读《C++ Primer》的重载运算符章节,作者给出了一个例子:

// member binary operator: left-hand operand bound to implicit this pointer
Sales_item& Sales_item::operator+=(const Sales_item&);
// nonmember binary operator: must declare a parameter for each operand
Sales_item operator+(const Sales_item&, const Sales_item&);

接下来,作者解释道:

这种区别与应用于算术类型时这些运算符的返回类型相匹配:加法产生一个右值,而复合赋值则返回左操作数的引用。

我不太确定 "复合赋值则返回左操作数的引用" 是什么意思。有人能详细解释一下吗?


查找方法链接。它基本上意味着a = b返回a,所以c = a = b计算为c = (a = b)a = b然后c = a都在一个语句中。 - chris
2个回答

5
这意味着你可以做类似以下的事情:
a = 1; 
(a += 1) += 1;

结果将是 a == 3. 原因是左侧的 += 调用修改了 a 并返回对它的引用。接下来的 += 操作再次对引用的 a 添加数字。

另一方面,普通的 + 操作符返回一个结果的 副本,而不是一个参数的引用。这意味着表达式 a + a = 3; 是非法的。


@Robᵩ:他肯定对此有把握。但这并不意味着他是正确的。因错误回答扣1分。 - Nawaz
1
@Nawaz:我觉得这个踩票有点过分了,因为它只需要加上一对括号就可以解决。答案已经捕捉到了复合赋值的本质,所以因为Davis在一个简单的问题(白板的产物)上犯错而失败似乎有点过于苛刻了。 - Matthieu M.
@Nawaz,不是的,这只是对OP的Sales_item::operator+=()例程进行了两次连续调用。这与任何其他构造一样有效,例如obj.funct().another()。 - Davis King
@DavisKing:你的例子中数据类型是int,它没有operator+=作为函数;换句话说,表达式(a+=1)不会引入任何序列点(据我所知)。 - Nawaz
@Nawaz,我的意思是让a具有Sales_item类型,并且我假设它可以从int构造出来,以使示例更简单。但是对于int,我不确定+=是否单独引入序列点,或者是否需要介入;。我们可以将语句分解并放入显式引用,例如int& rval = (a+=1); rval += 1;,但我认为这会使答案更加混乱。 - Davis King
显示剩余2条评论

2
a = a + b;

也是

a += b;

这相当于

a.operator+= (b)

operator += 支持复合赋值:

(a += b) += c;

等同于

a.operator+= (b).operator+= (c);

最后一行如果返回一个值而不是rvalue将不可能实现。
考虑以下代码:
c = a + b;

也是

c = a.operator+ (b);

写作

a.operator+ (b) = c;

没有影响,因为a的值没有改变。


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