在C ++中编写这样的代码时:
bool allTrue = true;
allTrue = allTrue && check_foo();
allTrue = allTrue && check_bar();
如果check_bar()
返回check_foo()
,则不会评估 false
。这称为short-circuiting or short-circuit evaluation,是懒惰评估原则的一部分。
这是否适用于复合赋值运算符&=
?
bool allTrue = true;
allTrue &= check_foo();
allTrue &= check_bar(); //what now?
对于逻辑OR
,将所有&
替换为|
,将true
替换为false
。
答案 0 :(得分:39)
来自C ++ 11 5.17 Assignment and compound assignment operators
:
E1 op = E2形式的表达式的行为等同于E1 = E1 op E2,除了E1仅被评估一次。
但是,你混淆了做短路的逻辑AND,以及从未做过的按位AND。
文本摘要&&=
,就像你要做的那样,在标准中找不到无处。原因是它实际上并不存在:没有逻辑和赋值运算符。
答案 1 :(得分:10)
短路(即懒惰)评估仅适用于逻辑&&
和||
。按位&
和|
评估两个参数。
答案 2 :(得分:7)
不,他们不会做空。
请注意,&=
和|=
运算符形成为&
+ =
和|
+ =
。 位操作符 &
和|
不执行快捷方式评估。
只有布尔运算符 &&
和||
执行它。
这意味着,快捷操作符必须传统上命名为&&=
和||=
。有些语言提供它们。 C / C ++没有。
答案 3 :(得分:3)
代码allTrue &= check_foo();
相当于allTrue = allTrue & check_foo()
您正在使用bitwise AND
并且不执行延迟评估。
bitwise AND
必须使用两个参数,其二进制表示具有相同的长度,并使用logical AND
操作来比较每个对应的位。
答案 4 :(得分:1)
首先:a &= b;
与a = a && b;
不同。 a &= b;
表示a = a & b;
。在C / C ++中没有a &&= b;
。
逻辑AND a && b
有点像1位测试。如果第一个"位"已经为0,结果总是为0,无论第二个。因此,如果b
已经明确了结果,则无需评估a
。 C / C ++标准允许这种优化。
按位AND a & b
对a
和b
的所有位执行此测试。因此,如果b
中的至少一位不为零,则需要评估a
。您可能希望如果a==0
不会评估b
,那么C / C ++中不允许进行此优化。
答案 5 :(得分:0)
从&是一个位操作,首先评估check_foo(),而不管allTrue的值是什么
allTrue &= check_foo(); // also for allTrue = allTrue & check_foo();
以及
allTrue &= check_bar(); // also for allTrue = allTrue & check_bar();
但是,如果您使用&&amp ;;则不会调用check_foo()和alltrue是假的,如:
allTrue = allTrue && check_foo();