每个内置复合赋值表达式E1 op= E2
的行为(其中E1
是一个可修改的左值表达式,而E2
是一个右值表达式或一个带括号的 init 列表(因为 C ++ 11))与表达式E1 = E1 op E2
的行为完全相同E1
我想知道这个解释是错误的(不足)还是我理解不正确。
我理解E1 = E1 + E2
和E1 += E2
之间有固有的区别,解释为here:
#include<iostream>
int main() {
int x;
x = 1;
x += (-1) ? 2 : 2;
std::cout << x << std::endl; //prints 3
x = 1;
x = x + (-1) ? 2 : 2;
std::cout << x << std::endl; //prints 2
x = 2;
x += (-2) == 0;
std::cout << x << std::endl; //prints 2
x = 2;
x = x + (-2) == 0; // prints 1
}
我的猜测是E1 op= E2
有以下行为:
评估E1
和E2
(不确定顺序),并将两次评估之间的运算结果分配给E1
,即(E1) = (E1) op (E2)
。
那么,对复合赋值运算的行为的更好解释是(E1) = (E1) op (E2)
?(或E1 = E1 op (E2)
,因为E1
只能具有比赋值运算符更高的优先级和比 op 运算符更低的优先级的运算符,如果E1 op (E2)
想要产生与(E1) op (E2)
不同的结果。不存在其结果是可修改的 lvalue 的运算符)。
来自 cppreference 的引用直接来自 C ++ 标准:
[expr.]/6
E1 op= E2
形式的表达式的行为应完全等同于E1 = E1 op E2
,但E1
只计算一次。
如果E1
具有volatile-qualified类型,则不建议使用此类表达式;请参阅[depr.volatile.type]
。
对于+=
和
在这种情况下,the term expression has already been defined和E1 op= E2
等同于E1 = E1 op E2
显然并不意味着表达式在文本表示上是等效的,而是在分辨率(类型,值和副作用)上。
[A] 更好的解释复合赋值操作的行为可能是(E1)=(E1)OP(E2)?
我只能表达我的观点:我认为cpprederence 页面在这里引用标准是正确的,但是可以添加注释以确保读者不会弄错。
这是关于运算符优先级。+
具有比三元条件更高的优先级 (还有==
)。所以这:
x = x + (-1) ? 2 : 2;
是这样评估的:
x = (x + (-1)) ? 2 : 2;
这就是为什么你得到2
而不是3
。
x = x + (-2) == 0
被评估为
x = (x + (-2)) == 0 // (x + (-2)) is 0, 0 == 0 is 1
所以拿第一个例子:
x = x + (-1) ? 2 : 2;
这里A
是x
,B
是(x + (-1) ? 2 : 2)
(x
加上三元运算的结果)
然而,在这里
x += (-1) ? 2 : 2;
A
是x
,而B
只是三元运算的结果。A
和B
由于+=
的优先级低于=
而发生了变化。因此,关于 E1 = E1 E2 和 E1 = E2的说法是相同的,
根据 C ++ 标准(8.5.18 赋值和复合赋值运算符)
7 形式为 E1 op = E2 的表达式的行为等同于 E1 = E1 op E2,除了 E1 只计算一次。在 + = 和-= 中,E1 应具有算术类型或指向可能是 cv 限定的完全定义的对象类型的指针。在所有其他情况下,E1 应具有算术类型。
和 (8.5.6 加法运算符)
1加法运算符 + 和-从左到右分组。通常的算术转换(8.3)是针对算术或枚举类型的操作数执行的。
这些表达式语句
x = x + (-1) ? 2 : 2;
x += (-2) == 0;
x = x + (-2) == 0;
相当于
x = ( x - 1 ) ? 2 : 2;
x += ( -2 == 0 );
x = ( ( x - 2 ) == 0 );
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(57条)