当我使用i++++
时发出编译错误:
for (int i=1;i<=10;i++++) {} //a.cpp:63: error: lvalue required as increment operand
或
int i = 0;
i++++; // a.cpp:65: error: lvalue required as increment operand
但是当我使用++++i
时正在运行。有人解释为什么++++i
有规律但i++++
不规律吗?
感谢。
答案 0 :(得分:13)
由于x
的类型是内置基元类型,因此两个表达式都会调用未定义的行为,因为两个表达式都尝试在两个序列之间修改相同的对象两次点。
不要做其中任何一个。
阅读此常见问题:
Undefined behavior and sequence points
但是,如果x
的类型是用户定义的类型,并且您为两个表达式重载了operator++
,则两者都将定义明确。
为此,请参阅此主题以了解说明和详细信息:
答案 1 :(得分:6)
C ++标准在5.2.6节中说i ++的结果是一个可修改的左值,而在5.3.2中,++ i的结果是一个可修改的左值。这有助于解释为什么i ++++和++++ i不需要生成诊断并且有时可能会起作用。
然而,++++ i在前一个和下一个序列点之间修改了两次,因此结果仍然是未定义的行为。 ++++我被允许工作,但它没有。
幸运的是,您的编译器诊断出i ++++。
答案 2 :(得分:5)
因为运营商的概念“签名”是:
T& operator ++(T& a); // pre
T operator ++(T& a, int); // post
// note the int is solely to distinguish the two
一个返回引用(左值),另一个不返回。但是,两者都将引用作为参数,因此返回引用(++i
)的引用可以链接,而不引用(i++
)的引用则不能链接。
请注意,正如@Nawaz所说的那样,有效的行为会调用未定义的行为,就像那个假设行为不起作用的行为一样。
答案 3 :(得分:3)
正如有些人所说,++++i
被编译器接受,但是当它被评估时,它会在C ++ 03中产生未定义的行为。
请注意,简单地说sizeof(++++i)
很好,因为没有评估任何内容。说++++i
在C ++ 11中很好,即使它被评估了。
答案 4 :(得分:1)
要从“你想做什么”视图中回答这个问题:没有必要开始调用i++++
,因为i++
不会返回引用增加i
变量,但值i
在之前有增量。所以i++++
基本上会这样做:
i
复制到临时变量t
i
t
复制到临时变量u
t
t
和u
所以剩下的就是i
的一个增量。
另一方面,++++i
只是
i
i
这确实很有用,而不是在整数类型中,但当i
是非随机访问迭代器时,因为那时你不能依赖i+=2
。