Kurze Antwort
Alle Betreiber +=
, -=
, *=
, /=
, &=
, |=
... sind arithmetische und bieten gleiche Erwartung:
x &= foo() // We expect foo() be called whatever the value of x
Operatoren &&=
und ||=
wären jedoch logisch, und diese Operatoren könnten fehleranfällig sein, da viele Entwickler erwarten würden foo()
, immer aufgerufen zu werden 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
Müssen wir C / C ++ wirklich noch komplexer machen, um eine Verknüpfung zu erhalten x = x && foo()
?
Wollen wir die kryptische Aussage wirklich mehr verschleiern x = x && foo()
?
Oder wollen wir aussagekräftigen Code schreiben wie if (x) x = foo();
?
Lange Antwort
Beispiel für &&=
Wenn der &&=
Operator verfügbar war, dann dieser Code:
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
ist äquivalent zu:
bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true
Dieser erste Code ist fehleranfällig, da viele Entwickler glauben, dass er f2()
immer unabhängig vom f1()
zurückgegebenen Wert aufgerufen wird. Es ist wie beim Schreiben, bool ok = f1() && f2();
wo f2()
nur bei der f1()
Rückkehr aufgerufen wird true
.
- Wenn der Entwickler tatsächlich
f2()
nur bei der f1()
Rückgabe aufgerufen werden möchte , ist true
der zweite Code oben weniger fehleranfällig.
- Sonst (der Entwickler möchte
f2()
immer angerufen werden) &=
ist ausreichend:
Beispiel für &=
bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value
Darüber hinaus ist es für den Compiler einfacher, diesen obigen Code zu optimieren als den folgenden:
bool ok = true;
if (!f1()) ok = false;
if (!f2()) ok = false; //f2() always called
Vergleiche &&
und&
Wir fragen uns vielleicht, ob die Operatoren &&
und &
das gleiche Ergebnis bool
liefern, wenn sie auf Werte angewendet werden.
Überprüfen wir dies mit dem folgenden C ++ - Code:
#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);
}
Ausgabe:
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
======================
Fazit
Daher JA können wir ersetzen &&
durch &
für bool
Werte ;-)
Also besser nutzen &=
statt &&=
.
Wir können &&=
für Boolesche als nutzlos betrachten.
Gleiches gilt für ||=
Betreiber |=
ist auch weniger fehleranfällig als||=
Wenn ein Entwickler f2()
nur bei der f1()
Rückgabe angerufen werden möchte false
, anstatt:
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 ...
Ich rate die folgende verständlichere Alternative:
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)
oder wenn Sie alle in einem Linienstil bevorzugen :
// 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();