Необходимо проверить на AI (Искусственный интеллект) книги. Я имею, узнают о Байесовском в Искусственный интеллект "Современный подход ".
Согласно 4.7 (Интегральные преобразования), параграф 4 , "Если тип назначения - bool
, см. 4.12. Если тип источника - bool
, значение false
преобразуется в ноль, а значение true
преобразуется в единицу ". В версии 4.12 «r-значение арифметики, перечисления, указателя или указателя на тип элемента может быть преобразовано в r-значение типа bool
. Нулевое значение, значение нулевого указателя, или значение указателя нулевого члена преобразуется в false
; любое другое значение преобразуется в true
. "
В контексте, где операнды bool
не разрешены, а целочисленные операнды разрешены, bool
будет преобразовано в целочисленный тип. Когда целочисленный результат сохраняется в переменной bool
, он будет преобразован в bool
.
Таким образом, вы сможете использовать + и * как логические или and and, и вы можете использовать | и также. Вы не можете избежать их смешивания, поскольку (bool1 + bool2) & bool3 выдаст false
, если все три переменные true
. ((1 + 1) & 1 равно 2 & 1, что равно 0 или ложь.)
Помните, что | и || не работают одинаково даже здесь. | Будет оценивать обе стороны, а затем оцените побитовое или. || оценит первый операнд, тогда только если это было ложно, оценит второй.
Я не собираюсь обсуждать здесь стилистические проблемы, но если бы я сделал что-то подобное, я обязательно прокомментировал бы это, чтобы люди знали что я делал и почему.
Стандартный говорит:
4.5-4 «Интегральные продвижения»
Значение типа bool может быть преобразовано в rvalue типа int, с ложным становится нулевым и истинным становится единым.
5.17-7 «Операторы присваивания»
Поведение выражения форма E1 op = E2 эквивалентна E1 = E1 op E2, за исключением того, что E1 оценивается только однажды. В + = и - = E1 должен либо иметь арифметический тип, либо быть указатель на возможно cvqualified полностью определенный тип объекта. В целом в других случаях E1 должен иметь арифметические тип.
4.12-1 "Булевы преобразования"
Значение r арифметики, перечисления, указатель или указатель на тип элемента может быть преобразованным в rvalue типа булево. Нулевое значение, нулевой указатель значение или значение указателя нулевого члена преобразован в ложь; любое другое значение преобразовано в истину.
Таким образом, это означает, что
b1 += b2
Где b1 и b2 являются логическими, будет эквивалентно
b1 = b1 + b2
И b1 и b2 будут преобразованы в целые числа 0/1, а затем преобразованы обратно в логические по правилу, что истинно все, кроме 0.
Таким образом, таблица истинности
true false true true true false true false
, так что + = действительно работает как || = согласно стандарту. Однако это, вероятно, запутает других программистов, поэтому я бы все равно этого избегал.
Не могли бы вы просто использовать тернарный оператор?
old_value =! Old_value? possible_new_value: old_value;
Не используйте | =
и & =
с bools. Они могут работать большую часть времени, но это все равно неправильно. Обычно тип bool - это просто прославленный int или char. В более старом коде, с которым я работал, BOOL просто определяется типом int или char. В этих случаях вы можете получить неправильный ответ, если каким-то образом были изменены биты (например, 1 & 2
равно 0 (ложь)). И я не уверен, но я думаю, что результат побитовых операторов будет int, даже для bools.
Одно отличие состоит в том, что логические операторы, такие как ||
, гарантируют порядок вычисления и обеспечивают сокращение, в отличие от побитовых и арифметических операторов.
Я считаю, что компилятор будет обрабатывать нелогические операторы путем преобразования bools в числовые значения (0, 1), применяя оператор и конвертируя обратно. Эти преобразования строго определены стандартом, например:
r-значение арифметики, перечисления, указателя или указателя на тип элемента может быть преобразовано в r-значение типа bool. Нулевое значение, значение нулевого указателя или значение указателя нулевого члена преобразуются в ложь, любое другое значение преобразуется в истину.
if (!old_value)
old_value = possible_new_value;
Это прямой эквивалент исходного состояния. Он мог бы генерировать более простой код, поскольку он не всегда будет присваиваться old_value
- но я не ожидал бы, что разницу в производительности будет легко измерить в большой программе.
Я считаю, что стандарт явно определяет истину и ложь как 1 и 0, поэтому вы можете безопасно использовать побитовые операторы для значений bool
. Другие типы, которые могут неявно обрабатываться как bools в другом контексте, должны быть явно преобразованы, чтобы это работало надежно.
Я видел, как компилятор Microsoft генерирует уродливое предупреждение каждый раз, когда вы делаете это, потому что он думает, что существует опасность неявного преобразования результат int возвращается в bool.
Грязное взлом макросов:
#define UPDATE(x) x = x
UPDATE(old_value) || possible_new_value;
Но я не рекомендую это вообще. Подобные макросы - очень плохая идея по нескольким причинам.
Более нормальная функция, но без короткого замыкания:
bool set_or(bool &old, bool value) {
return (old = old || value);
}
...
bool v = false;
set_or(v, true);