Risposta breve
Tutti gli operatori +=
, -=
, *=
, /=
, &=
, |=
... sono l'aritmetica e forniscono stessa aspettativa:
x &= foo() // We expect foo() be called whatever the value of x
Tuttavia, gli operatori &&=
e ||=
sarebbero logici e questi operatori potrebbero essere soggetti a errori perché molti sviluppatori si aspetterebbero di foo()
essere sempre chiamati 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
Dobbiamo davvero rendere C / C ++ ancora più complesso per ottenere una scorciatoia x = x && foo()
?
Vogliamo davvero offuscare di più l'affermazione criptica x = x && foo()
?
O vogliamo scrivere un codice significativo come if (x) x = foo();
?
Risposta lunga
Esempio per &&=
Se l' &&=
operatore era disponibile, questo codice:
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
è equivalente a:
bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true
Questo primo codice è soggetto a errori perché molti sviluppatori pensano che f2()
sia sempre chiamato qualunque sia il f1()
valore restituito. È come scrivere bool ok = f1() && f2();
dove f2()
viene chiamato solo quando f1()
ritorna true
.
- Se lo sviluppatore in realtà vuole
f2()
essere chiamato solo quando f1()
ritorna true
, quindi il secondo codice sopra è meno soggetto a errori.
- Altrimenti (lo sviluppatore vuole
f2()
essere sempre chiamato), &=
è sufficiente:
Esempio per &=
bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value
Inoltre, è più facile per il compilatore ottimizzare questo codice sopra rispetto a quello sotto:
bool ok = true;
if (!f1()) ok = false;
if (!f2()) ok = false; //f2() always called
Confronta &&
e&
Potremmo chiederci se gli operatori &&
e &
dare lo stesso risultato quando applicati ai bool
valori?
Controlliamo utilizzando il seguente codice 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);
}
Produzione:
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
======================
Conclusione
Pertanto SÌ possiamo sostituire &&
da &
per bool
valori ;-)
Quindi, l'uso migliore &=
, invece di &&=
.
Possiamo considerare &&=
inutili i booleani.
Lo stesso per ||=
l'operatore |=
è anche meno soggetto ad errori di||=
Se uno sviluppatore vuole f2()
essere chiamato solo quando f1()
ritorna false
, anziché:
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 ...
Consiglio la seguente alternativa più comprensibile:
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)
o se preferisci tutto in uno stile di linea :
// 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();