Краткий ответ
Все операторы +=
, -=
, *=
, /=
, &=
, |=
... являются арифметическими и дают одинаковое ожидание:
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
Нам действительно нужно сделать C / C ++ еще более сложным, чтобы получить ярлык для x = x && foo()
?
Неужели мы действительно хотим больше запутать загадочное утверждение x = x && foo()
?
Или мы хотим написать значимый код вроде if (x) x = foo();
?
Длинный ответ
Пример для &&=
Если оператор &&=
был доступен, то этот код:
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
Этот первый код подвержен ошибкам , потому что многие разработчики думают, что f2()
всегда вызывается независимо от возвращаемого значения f1()
. Это похоже на запись 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
======================
Заключение
Поэтому ДА мы можем заменить &&
на &
для bool
значений ;-)
Так что лучше используйте &=
вместо &&=
.
Мы можем считать &&=
бесполезным для логических значений.
То же самое для ||=
оператор |=
также меньше подвержен ошибкам , чем ||=
Если разработчик хочет, чтобы f2()
вызывался только тогда, когда f1()
возвращает false
вместо:
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();