简答
所有运算符+=、-=、*=、/=、&=、|=...都是算术运算符并提供相同的期望:
x &= foo() // We expect foo() be called whatever the value of x
但是,运算符 &&= 和 ||= 是合乎逻辑的,并且这些运算符可能容易出错,因为许多开发人员希望 foo() 总是在 x &&= foo() 中调用。
bool x;
// ...
x &&= foo(); // Many developers might be confused
x = x && foo(); // Still confusing but correct
x = x ? foo() : x; // Understandable
x = x ? foo() : false; // Understandable
if (x) x = foo(); // Obvious
长答案
&&= 的示例
如果&&= 运算符可用,则此代码:
bool ok = true; //becomes false when at least a function returns false
ok &&= f1();
ok &&= f2(); //we may expect f2() is called whatever the f1() returned value
相当于:
bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true
第一个代码容易出错,因为许多开发人员会认为无论f1() 返回值如何,总是调用f2()。这就像写bool ok = f1() && f2();,其中f2() 仅在f1() 返回true 时被调用。
- 如果开发者真的希望
f2() 仅在f1() 返回true 时被调用,那么上面的第二个代码更不容易出错。
- 否则(开发人员希望始终调用
f2()),&= 就足够了:
&= 的示例
bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value
此外,编译器优化上面的代码比优化下面的代码更容易:
bool ok = true;
if (!f1()) ok = false;
if (!f2()) ok = false; //f2() always called
比较 && 和 &
我们可能想知道运算符&& 和& 在应用于bool 值时是否给出相同的结果?
让我们使用以下 C++ 代码进行检查:
#include <iostream>
void test (int testnumber, bool a, bool b)
{
std::cout << testnumber <<") a="<< a <<" and b="<< b <<"\n"
"a && b = "<< (a && b) <<"\n"
"a & b = "<< (a & b) <<"\n"
"======================" "\n";
}
int main ()
{
test (1, true, true);
test (2, true, false);
test (3, false, false);
test (4, false, true);
}
输出:
1) a=1 and b=1
a && b = 1
a & b = 1
======================
2) a=1 and b=0
a && b = 0
a & b = 0
======================
3) a=0 and b=0
a && b = 0
a & b = 0
======================
4) a=0 and b=1
a && b = 0
a & b = 0
======================
结论
因此 YES 我们可以将 && 替换为 & 以获得 bool 值 ;-)
所以最好使用&= 而不是&&=。
我们可以认为&&= 对布尔值没有用处。
||= 相同
操作员|= 也比||= 更不容易出错
如果开发人员希望仅在f1() 返回false 时调用f2(),而不是:
bool ok = false;
ok ||= f1();
ok ||= f2(); //f2() is called only when f1() returns false
ok ||= f3(); //f3() is called only when f1() or f2() return false
ok ||= f4(); //f4() is called only when ...
我建议以下更容易理解的替代方案:
bool ok = false;
if (!ok) ok = f1();
if (!ok) ok = f2();
if (!ok) ok = f3();
if (!ok) ok = f4();
// no comment required here (code is enough understandable)
或者如果你更喜欢一行风格:
// this comment is required to explain to developers that
// f2() is called only when f1() returns false, and so on...
bool ok = f1() || f2() || f3() || f4();