我真正想要的是一个|| =运算符。
old_value = old_value || possible_new_value;
old_value ||= possible_new_value;
第二行是编译器错误(c ++没有|| =运算符)。
那么我的其他选择是什么?
old_value += possible_new_value;
old_value |= possible_new_value;
当我谈到这个问题时,bool如何与其他非布尔运算符一起运行?
-
-=
&
&=
...
我可以凭经验验证这些,但我最感兴趣的是标准所说的内容。
答案 0 :(得分:12)
根据4.7(积分转换)第4段,“如果目的地类型为bool
,请参阅4.12。如果源类型为bool
,则值false
将转换为零,值true
转换为一。“在4.12中,“算术,枚举,指针或指向成员类型的指针的右值可以转换为类型bool
的右值。零值,空指针值或空成员指针值转换为{{ 1}};任何其他值都转换为false
。“
在不允许true
个操作数但是整数操作数的情况下,bool
将转换为整数类型。当整数结果存储在bool
变量中时,它将转换为bool
。
因此,您可以使用+和*作为布尔值或和,并且您可以使用|和&也。你不能把它们混合起来,如(bool1 + bool2)&如果所有三个变量都是bool
,bool3将产生false
。 ((1 + 1)& 1是2& 1,它是0或假。)
记住|和||即使在这里,也不要完全相同。 |将评估双方,然后评估按位或。 ||将评估第一个操作数,然后只有当它为假时才会评估第二个操作数。
我不打算在这里讨论风格问题,但如果我做了类似的事情,我一定会发表评论,以便人们知道我在做什么以及为什么。
答案 1 :(得分:4)
标准说:
4.5-4“整体促销”
bool类型的右值可以是 转换为int类型的右值, 错误变为零和真实 成为一个。
5.17-7“分配运营商”
表达式的行为 形式E1 op = E2相当于E1 = E1 op E2除了评估E1之外 只有一次。在+ =和 - =中,E1应该 要么是算术类型要么是a 指向可能是cvqualified的指针 完全定义的对象类型。在所有 其他情况下,E1应具有算术运算 类型。
4.12-1“布尔转化”
算术,枚举的右值, 指针或指向成员类型的指针可以 转换为类型的右值 布尔。零值,空指针 value或null成员指针值是 转换为假;任何其他价值 转换为真。
所以这意味着
b1 += b2
其中b1和b2是布尔值,相当于
b1 = b1 + b2
b1和b2将被提升为0/1整数,然后根据0以外的任何值为真的规则转换回布尔值。
所以真值表是
true false true true true false true false
所以+ =确实按照标准工作为|| =。但是,这可能会让其他程序员感到困惑,所以我会避免它。
答案 2 :(得分:1)
你能使用三元运算符吗?
old_value = !old_value ? possible_new_value : old_value;
答案 3 :(得分:0)
不要将|=
和&=
与bool一起使用。他们大部分时间都可以工作,但这仍然是错误的。通常bool类型只是一个美化的int或char。在我使用的旧代码中,BOOL只是对int或char的类型定义。在这些情况下,如果某些位被操纵,您可能会得到错误的答案(例如,1&2
为0(false))。而且我不确定,但我认为按位运算符的结果将是一个整数,即使对于bools也是如此。
答案 4 :(得分:0)
if (!old_value)
old_value = possible_new_value;
这是原始条件的直接等价物。它可能会生成更简单的代码,因为它不会总是分配给old_value
- 但我不希望性能差异在大型程序中很容易测量。
答案 5 :(得分:0)
一个不同之处在于,||
等逻辑运算符保证了评估的顺序并提供了短路,而逐位运算符和算术运算符则没有。
我相信编译器会通过将bool转换为应用运算符并转换回来的数值(0,1)来处理非逻辑运算符。这些转换由标准严格定义,例如:
算术,枚举,指针或指向成员类型的指针的右值可以转换为bool类型的右值。零值,空指针值或空成员指针值将转换为false,任何其他值都将转换为true。
答案 6 :(得分:0)
讨厌的宏hackery:
#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);
答案 7 :(得分:0)
我相信标准明确地将true和false定义为1和0,因此您可以安全地在bool
值上使用按位运算符。其他可能在另一个上下文中被隐式视为bool的类型应该被明确转换,以使其可靠地工作。
我看到微软的编译器每次都会生成一个丑陋的警告,因为它认为将int结果隐式转换回bool存在危险。