Respuesta corta
Todos los operadores +=
, -=
, *=
, /=
, &=
, |=
... son la aritmética y proporcionan misma expectativa:
x &= foo() // We expect foo() be called whatever the value of x
Sin embargo, los operadores &&=
y ||=
sería lógico, y estos operadores podrían ser propenso a errores debido a que muchos desarrolladores se pueden esperar foo()
ser siempre llamaron 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
¿Realmente necesitamos hacer que C / C ++ sea aún más complejo para obtener un atajo x = x && foo()
?
¿Realmente queremos ofuscar más la declaración críptica x = x && foo()
?
¿O queremos escribir código significativo como if (x) x = foo();
?
Respuesta larga
Ejemplo para &&=
Si el &&=
operador estaba disponible, entonces este código:
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
es equivalente a:
bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true
Este primer código es propenso a errores porque muchos desarrolladores pensarían que f2()
siempre se llama cualquiera que sea el f1()
valor devuelto. Es como escribir bool ok = f1() && f2();
donde f2()
se llama solo cuando f1()
regresa true
.
- Si el desarrollador realmente quiere
f2()
ser llamado solo cuando f1()
regrese true
, por lo tanto, el segundo código anterior es menos propenso a errores.
- De lo contrario (el desarrollador quiere
f2()
ser llamado siempre), &=
es suficiente:
Ejemplo para &=
bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value
Además, es más fácil para el compilador optimizar este código anterior que el siguiente:
bool ok = true;
if (!f1()) ok = false;
if (!f2()) ok = false; //f2() always called
Compara &&
y&
Podemos preguntarnos si los operadores &&
y &
dar el mismo resultado cuando se aplica a los bool
valores?
Vamos a verificar usando el siguiente código 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);
}
Salida:
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
======================
Conclusión
Por lo tanto SÍ se puede sustituir &&
por &
de bool
valores ;-)
Así que utilice mejor &=
en lugar de &&=
.
Podemos considerarlo &&=
inútil para los booleanos.
Igual por ||=
El operador |=
también es menos propenso a errores que||=
Si un desarrollador quiere f2()
ser llamado solo cuando f1()
regrese false
, en lugar de:
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 ...
Aconsejo la siguiente alternativa más comprensible:
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 si prefiere todo en un estilo de línea :
// 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();