位级运算符的缺点。
你问:
“有什么理由不使用位运算符&、| 和^ 来表示C++ 中的“布尔”值吗? ”
是的,逻辑运算符,即内置的高级布尔运算符!、&& 和||,具有以下优点:
保证参数转换到bool,即到0和1序数值。
保证短路评估,一旦知道最终结果,表达式评估就会停止。
这可以解释为树值逻辑,具有 True、False 和 Indeterminate。
可读的文本等价物 not、and 和 or,即使我自己不使用它们。
正如读者 Antimony 在评论中指出的那样,位级运算符也有替代标记,即 bitand、bitor、xor 和 compl,但在我看来,它们的可读性不如 and、or 和 @ 987654339@.
简单地说,高级运算符的每一个优点都是位级运算符的缺点。
特别是,由于按位运算符缺少到 0/1 的参数转换,因此您会得到例如1 & 2 → 0,而1 && 2 → true。还有^,按位排他或,可能会以这种方式行为不端。视为布尔值1和2相同,即true,但视为位模式它们是不同的。
如何在 C++ 中表达逻辑either/or。
然后你为这个问题提供一点背景,
“我有时会遇到我希望两个条件之一为真 (XOR) 的情况,所以我只是将 ^ 运算符放入条件表达式中。”
嗯,位运算符比逻辑运算符具有更高的优先级。这尤其意味着在混合表达式中,例如
a && b ^ c
你可能会得到意想不到的结果a && (b ^ c)。
改为只写
(a && b) != c
更简洁地表达你的意思。
对于多参数either/or,没有 C++ 运算符可以完成这项工作。例如,如果你写a ^ b ^ c,那么这不是一个表示“a、b 或c 都是真的”的表达式。相反,它说,“奇数个 a、b 和 c 是真的”,可能是其中 1 个或全部 3 个......
当a、b 和c 是bool 类型时,要表达一般的非此即彼,只需写
(a + b + c) == 1
或者,使用非bool 参数,将它们转换为bool:
(!!a + !!b + !!c) == 1
使用&= 来累积布尔结果。
您进一步详细说明,
“有时我还需要累积布尔值,&= 和 |=? 会很有用。”
嗯,这对应于检查是否分别满足 all 或 any 条件,de Morgan's law 告诉你如何从一个开始给对方。 IE。你只需要其中之一。原则上,您可以将*= 用作&&= 运算符(正如老乔治布尔发现的那样,逻辑与可以很容易地表示为乘法),但我认为这会使代码维护者感到困惑甚至误导。
同时考虑:
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 输出:
真的
错误的
结果不同的原因是位级别&= 没有提供其右侧参数到bool 的转换。
那么,您希望使用&= 获得哪些结果?
如果是前者,true,那么最好定义一个运算符(例如,如上所述)或命名函数,或者使用右侧表达式的显式转换,或者完整地编写更新。