Делаете ли операторы & = и | = для короткого замыкания bool?
При написании кода в С++:
bool allTrue = true;
allTrue = allTrue && check_foo();
allTrue = allTrue && check_bar();
check_bar()
не будет оцениваться, если check_foo()
возвращен false
. (Это, по-видимому, называется ленивая оценка
EDIT: Или нет, как указано в комментариях. Он называется короткого замыкания или короткого замыкания, но является частью ленивого принципа оценки)
Это работает с оператором составного назначения &=
?
bool allTrue = true;
allTrue &= check_foo();
allTrue &= check_bar(); //what now?
Для логического OR
замените все &
на |
и true
на false
.
Ответы
Ответ 1
Из С++ 11 5.17 Assignment and compound assignment operators
:
Поведение выражения E1 op = E2 эквивалентно E1 = E1 op E2, за исключением того, что E1 оценивается только один раз.
Однако вы смешиваете логический И, который делает короткое замыкание, и побитовое И, которое никогда не делает.
Текстовый фрагмент &&=
, который будет таким, как вы будете делать то, о чем вы просите, нигде не встречается в стандарте. Причина этого в том, что она фактически не существует: нет оператора логического и присваивания.
Ответ 2
Оценка короткого замыкания (т.е. ленивая) предназначена только для логических &&
и ||
. Побитовые &
и |
оценивают оба аргумента.
Ответ 3
Код allTrue &= check_foo();
эквивалентен allTrue = allTrue & check_foo()
В которой вы используете bitwise AND
, и никакая ленивая оценка не выполняется.
bitwise AND
должен принимать два аргумента, двоичное представление которых имеет одинаковую длину и использует операцию logical AND
для сравнения каждой соответствующей пары бит.
Ответ 4
Нет, они не обрезаются.
Обратите внимание, что операторы &=
и |=
формируются как &
+ =
и |
+ =
. Операторы бит &
и |
не выполняют оценку ярлыков.
Выполняем только логические операторы &&
и ||
.
Это означает, что сокращающий оператор должен быть традиционно назван &&=
и ||=
. Некоторые языки предоставляют их. C/С++ не делает.
Ответ 5
Во-первых: a &= b;
не совпадает с a = a && b;
. a &= b;
означает a = a & b;
. В C/С++ нет a &&= b;
.
Логический И a && b
бит, как тест для 1 бит. Если первый "бит" уже равен 0, результат будет всегда равен 0 независимо от второго. Поэтому нет необходимости оценивать b
, если результат уже ясен из a
. Стандарт C/С++ позволяет эту оптимизацию.
Побитовое И a & b
выполняет этот тест для всех битов a
и b
. Поэтому b
необходимо оценить, если хотя бы один бит в a
будет отличным от нуля. Возможно, вы захотите, чтобы if a==0
, чем b
не был оценен, но эта оптимизация не разрешена в C/С++.
Ответ 6
Так как и является бит-операцией, check_foo() будет сначала оцениваться независимо от значения allTrue в
allTrue &= check_foo(); // also for allTrue = allTrue & check_foo();
а также
allTrue &= check_bar(); // also for allTrue = allTrue & check_bar();
Однако check_foo() не будет вызываться, если вы используете && и alltrue ложно, как в:
allTrue = allTrue && check_foo();