0

在 C++ 中,

i = ++++j;

在代码中工作正常,但是当我使用时,

i = j++++;

我收到以下错误:

Operand for operator "++" must be an lvalue.

为什么我会收到此错误?

4

2 回答 2

7

后增量要求操作数应该是可修改的左值,但后增量的结果是不可修改的纯值(“纯”右值),该图显示了发生了什么:

i = (j++)++ ;
     ^  ^
     |  |
     |  Result is a prvalue, not a valid operand for subsequent post-increment
     Modifiable lvalue

如果您需要了解左值和右值之间的区别,那么了解C 和 C++中的左值和右值是一个很好的起点。从草案 C++ 标准部分5.2.6 增量和减量 [expr.post.incr]1段说(重点是我在随后的引文中):

后缀 ++ 表达式的值是其操作数的值。[注:获得的值是原始值的副本——尾注]操作数应为可修改的左值。[..]结果是prvalue。

更新

我在未定义的行为上重新编写了我的语言,因为这里与C++03C++11有所不同。

虽然第一个表达式显示:

i = ++++j ;

不会产生错误,但如果这是C++03并且j是基本类型,则这是未定义的行为,因为在序列点内多次修改它的值是未定义的。旧标准草案中的相关部分将是第 4 节5 表达式4段,其中说:

[...]在前一个和下一个序列点之间,一个标量对象的存储值最多只能通过表达式的评估修改一次。此外,只能访问先验值以确定要存储的值。对于完整表达式的子表达式的每个允许排序,都应满足本段的要求;否则行为未定义。

并给出了一些例子,其中之一如下:

i = ++i + 1; // the behavior is undefined

C++11中,语言更改对同一标量对象的副作用相对于同一对象的另一个副作用是无序的,则行为未定义。所以这实际上在C++11中有很好的定义,在1.9 程序执行15段中说:

除非另有说明,否则单个运算符的操作数和单个表达式的子表达式的求值是无序的。[...]如果标量对象的副作用相对于同一标量对象的另一个副作用或使用同一标量对象的值的值计算是无序的,则行为未定义。

以这种方式使用后增量和前增量不会导致可读(可维护)的代码在这两种情况下使用j +=2之前或之后的赋值语句就足够了

于 2013-09-16T02:28:34.650 回答
1

您收到此错误是因为后缀运算符返回一个值而不是引用。但是为了清楚起见,您可能不应该这样做,将这些行说成或分隔成ori=j++++;可能会更清楚。i = j += 2;i = j+2; j+=2;j+=2; i = j;

于 2013-09-16T02:22:21.647 回答