Недостатки операторов битового уровня.
Вы спрашиваете:
& ldquo; Есть ли причина не использовать побитовые операторы &
, |
и ^
для значений "bool" в C ++? & Rdquo;
Да, логические операторы , то есть встроенные логические операторы высокого уровня !
, &&
и ||
, обладают следующими преимуществами:
Гарантированное преобразование аргументов в bool
, то есть в 0
и 1
порядковое значение.
Гарантировано Оценка короткого замыкания , где оценка выражения останавливается, как только известен конечный результат.
Это можно интерпретировать как древовидную логику с True , False и Indeterminate .
Текстовые эквиваленты для чтения not
, and
и or
, даже если я сам ими не пользуюсь.
Как отмечает в комментарии читатель Сурьма, операторы битового уровня также имеют альтернативные токены, а именно bitand
, bitor
, xor
и compl
, но, на мой взгляд, они менее читабельны, чем and
, or
и not
.
Проще говоря, каждое такое преимущество операторов высокого уровня является недостатком операторов уровня битов.
В частности, поскольку битовые операторы не имеют преобразования аргументов в 0/1, вы получаете, например, 1 & 2
& rarr; 0
, а 1 && 2
& rarr; true
. Также ^
, побитовое исключение или, может вести себя неправильно. Рассматриваемые как логические значения 1 и 2 одинаковы, а именно true
, но рассматриваются как битовые шаблоны, они разные.
Как выразить логическое либо / или в C ++.
Затем вы предоставите немного фона для вопроса,
& ldquo; Иногда я сталкиваюсь с ситуациями, когда требуется, чтобы одно из двух условий было истинно (XOR), поэтому я просто добавляю оператор ^ в условное выражение. & Rdquo;
Ну, побитовые операторы имеют более высокий приоритет , чем логические операторы. В частности, это означает, что в смешанном выражении, таком как
a && b ^ c
вы можете получить неожиданный результат a && (b ^ c)
.
Вместо этого напишите просто
(a && b) != c
выразить более кратко, что вы имеете в виду.
Для множественного аргумента либо / или нет оператора C ++, который выполняет эту работу. Например, если вы напишите a ^ b ^ c
, это не будет выражением, в котором говорится, что & ldquo; a
, b
или c
- true & ldquo ;. Вместо этого он говорит: «Нечетное число a
, b
и c
истинно», которое может быть 1 из них или все 3 «hellip;
».
Чтобы выразить общее, либо / или когда a
, b
и c
имеют тип bool
, просто напишите
(a + b + c) == 1
или, с не bool
аргументами, преобразовать их в bool
:
(!!a + !!b + !!c) == 1
Использование &=
для накопления логических результатов.
Вы уточните,
& ldquo; Мне также иногда нужно накапливать логические значения, и &=
и |=?
могут быть весьма полезны. & Rdquo;
Что ж, это соответствует проверке, удовлетворяется ли соответственно все или любому условию, и закон Моргана говорит вам, как перейти от одного к другой. То есть вам нужен только один из них. В принципе, вы можете использовать *=
в качестве &&=
-оператора (поскольку, как обнаружил старый добрый Джордж Буль, логическое И очень легко можно выразить как умножение), но я думаю, что это озадачивает и, возможно, вводит в заблуждение тех, кто поддерживает код.
Рассмотрим также:
struct Bool
{
bool value;
void operator&=( bool const v ) { value = value && v; }
operator bool() const { return value; }
};
#include <iostream>
int main()
{
using namespace std;
Bool a = {true};
a &= true || false;
a &= 1234;
cout << boolalpha << a << endl;
bool b = {true};
b &= true || false;
b &= 1234;
cout << boolalpha << b << endl;
}
Вывод с помощью Visual C ++ 11.0 и g ++ 4.7.1:
true
false
Причина различий в результатах заключается в том, что битовый уровень &=
не обеспечивает преобразование в bool
своего аргумента в правой части.
Итак, какой из этих результатов вы хотите использовать &=
?
Если первое, true
, то лучше определить оператор (например, как указано выше) или именованную функцию, либо использовать явное преобразование выражения правой части, либо написать обновление полностью.