为什么后缀运算符设计为按值返回?

时间:2013-02-12 04:35:26

标签: c++ c++11 operator-overloading

特别是,前缀运算符的引用返回对我有意义 - 如果有人想对对象进行进一步的操作,它就很有用。

但是,我无法理解为什么后缀运算符被设计为按值返回。

它只是一个约定,还是有一个很好的理由为什么它是这样设计的(就像按值返回对postfix没有意义,但对前缀有意义?)

有人可以解释一下吗?

ANSWER

由于下面的答案,似乎后缀运算符必然必须按值返回(根据标准)。

但是,由于后缀运算符的语义要求(返回原始值,但之后将引用增加到原始值),并结合以下标准要求:

操作符重载是函数,因此必须在函数完成之前进行所有副作用。

正如下面David Rodriguez清楚解释的那样,分叉值似乎是语义要求的必然结果。

在这个上下文中,因为我们返回另一个值(不是原始引用,因为它会被函数的右括号更改),所以返回另一个值 by-value 似乎最有意义的。

4 个答案:

答案 0 :(得分:10)

后缀运算符是产生原始值然后修改对象的表达式。同时,操作符重载是函数,因此所有副作用必须在函数完成之前发生。获得所需语义的唯一方法是在应用更改之前复制对象的初始状态。必须通过值返回原始状态(如果返回引用,表达式的求值将在函数完成后产生对象的状态,因此将具有前缀运算符的语义,而不是后缀运算符的语义)

答案 1 :(得分:5)

这是约定,因为后修复的典型实现涉及创建函数本地的临时对象,同时使用前缀运算符递增最初传递的对象,然后返回临时对象。您不能返回对该本地对象的引用,因此需要按值返回。

您不能返回引用,因为本地对象只能在函数范围内保持活动状态,并且超出此范围的任何对它的访问都将导致未定义的行为。

答案 2 :(得分:3)

以下代码在C和C ++中定义良好:

int i = 7;
printf("%i\n", i++ + 2);

这将打印9到控制台,而i将是8.保证。

后缀增量/减量修改i,但它们返回i旧值。使用对象执行此操作的唯一方法是将当前值保存为新值,自行增量并返回保存的值。

答案 3 :(得分:3)

当然这是很好的理由。 后增量运算符会执行以下操作:

  1. 递增变量和
  2. 返回旧值。
  3. 无法将引用返回给变量的“旧值”。它消失了。