为什么 c++ 没有 &&= 或 ||= 用于布尔值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2488406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:38:37  来源:igfitidea点击:

Why doesn't c++ have &&= or ||= for booleans?

c++boolean-operations

提问by Kache

Is there a "very bad thing"that can happen &&= and ||= were used as syntactic sugar for bool foo = foo && barand bool foo = foo || bar?

是否有可能发生的“非常糟糕的事情”&&= 和 ||= 被用作bool foo = foo && barand 的语法糖bool foo = foo || bar

采纳答案by Konrad Rudolph

A boolmay only be trueor falsein C++. As such, using &=and |=is relatively safe (even though I don't particularly like the notation). True, they will perform bit operations rather than logical operations (and thus they won't short-circuit) but these bit operations follow a well-defined mapping, which is effectively equivalent to the logical operations, as long asboth operands are of type bool.1

Abool可能只在truefalse在 C++ 中。因此,使用&=and|=是相对安全的(尽管我不是特别喜欢这个符号)。没错,它们将执行位运算而不是逻辑运算(因此它们不会短路)但是这些位运算遵循明确定义的映射,这实际上等效于逻辑运算,只要两个操作数都是类型bool. 1

Contrary to what other people have said here, a boolin C++ must never have a different value such as 2. When assigning that value to a bool, it will be converted to trueas per the standard.

与其他人在这里所说的相反bool,C++ 中的 a 绝不能具有不同的值,例如2. 将该值分配给 a 时bool,它将true根据标准转换为。

The only way to get an invalid value into a boolis by using reinterpret_caston pointers:

将无效值放入 a 的唯一方法bool是使用reinterpret_caston 指针:

int i = 2;
bool b = *reinterpret_cast<bool*>(&i);
b |= true; // MAY yield 3 (but doesn't on my PC!)

But since this code results in undefined behaviour anyway, we may safely ignore this potential problem in conforming C++ code.

但是由于这段代码无论如何都会导致未定义的行为,我们可以安全地忽略符合 C++ 代码的这个潜在问题。



1Admittedly this is a rather big caveat as Angew's comment illustrates:

1诚然,这是一个相当大的警告,正如 Angew 的评论所示:

bool b = true;
b &= 2; // yields `false`.

The reason is that b & 2performs integer promotion such that the expression is then equivalent to static_cast<int>(b) & 2, which results in 0, which is then converted back into a bool. So it's true that the existence of an operator &&=would improve type safety.

原因是b & 2执行整数提升,使得表达式等价于static_cast<int>(b) & 2,结果为0,然后将其转换回 a bool。所以确实存在 anoperator &&=会提高类型安全性。

回答by Niki

&&and &have different semantics: &&will not evaluate the second operand if the first operand is false. i.e. something like

&&并且&有不同的语义:&&如果第一个操作数是 ,则不会评估第二个操作数false。即类似的东西

flag = (ptr != NULL) && (ptr->member > 3);

is safe, but

是安全的,但是

flag = (ptr != NULL) & (ptr->member > 3);

is not, although both operands are of type bool.

不是,尽管两个操作数都是 类型bool

The same is true for &=and |=:

&=和也是如此|=

flag = CheckFileExists();
flag = flag && CheckFileReadable();
flag = flag && CheckFileContents();

will behave differently than:

将与以下行为不同:

flag = CheckFileExists();
flag &= CheckFileReadable();
flag &= CheckFileContents();

回答by olibre

Short answer

简答

All the operators +=, -=, *=, /=, &=, |=... are arithmetic and provide same expectation:

所有的操作符+=, -=, *=, /=, &=, |=... 都是算术并且提供相同的期望:

x &= foo()  // We expect foo() be called whatever the value of x

However, operators &&=and ||=would be logical, and these operators might be error-prone because many developers would expect foo()be always called in x &&= foo().

然而,操作符&&=and||=是合乎逻辑的,而且这些操作符可能容易出错,因为许多开发人员希望foo()总是被调用x &&= foo()

bool x;
// ...
x &&= foo();           // Many developers might be confused
x = x && foo();        // Still confusing but correct
x = x ? foo() : x;     // Understandable
x = x ? foo() : false; // Understandable
if (x) x = foo();      // Obvious
  • Do we really need to make C/C++ even more complex to get a shortcut for x = x && foo()?

  • Do we really want to obfuscate more the cryptic statement x = x && foo()?
    Or do we want to write meaningful code like if (x) x = foo();?

  • 我们真的需要让 C/C++ 变得更加复杂才能获得 的捷径x = x && foo()吗?

  • 我们真的想混淆更多神秘的陈述x = x && foo()吗?
    或者我们想编写有意义的代码,例如if (x) x = foo();



Long answer

长答案

Example for &&=

示例 &&=

If &&=operator was available, then this code:

如果&&=操作员可用,则此代码:

bool ok = true; //becomes false when at least a function returns false
ok &&= f1();
ok &&= f2(); //we may expect f2() is called whatever the f1() returned value

is equivalent to:

相当于:

bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true

This first code is error-pronebecause many developers would think f2()is always called whatever the f1()returned value. It is like writing bool ok = f1() && f2();where f2()is called only when f1()returns true.

这第一个代码容易出错,因为许多开发人员认为f2()无论f1()返回值总是调用。这就像只在返回时才调用bool ok = f1() && f2();where一样。f2()f1()true

  • If the developer actually wants f2()to be called only when f1()returns true, therefore the second code above is less error-prone.
  • Else (the developer wants f2()to be always called), &=is sufficient:
  • 如果开发者实际想f2()要调用只有当f1()返回true,因此,第二代码是以上更不易出错。
  • 否则(开发人员希望f2()始终被调用),&=就足够了:

Example for &=

示例 &=

bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value

Moreover, it is easier for compiler to optimize this above code than that below one:

此外,编译器优化上面的代码比下面的代码更容易:

bool ok = true;
if (!f1())  ok = false;
if (!f2())  ok = false;  //f2() always called

Compare &&and &

比较&&&

We may wonder whether the operators &&and &give the same result when applied on boolvalues?

我们可能想知道运算符&&&应用于bool值时是否会给出相同的结果?

Let's check using the following C++ code:

让我们使用以下 C++ 代码进行检查:

#include <iostream>

void test (int testnumber, bool a, bool b)
{
   std::cout << testnumber <<") a="<< a <<" and b="<< b <<"\n"
                "a && b = "<< (a && b)  <<"\n"
                "a &  b = "<< (a &  b)  <<"\n"
                "======================"  "\n";
}

int main ()
{
    test (1, true,  true);
    test (2, true,  false);
    test (3, false, false);
    test (4, false, true);
}

Output:

输出:

1) a=1 and b=1
a && b = 1
a &  b = 1
======================
2) a=1 and b=0
a && b = 0
a &  b = 0
======================
3) a=0 and b=0
a && b = 0
a &  b = 0
======================
4) a=0 and b=1
a && b = 0
a &  b = 0
======================

Conclusion

结论

Therefore YESwe can replace &&by &for boolvalues ;-)
So better use &=instead of &&=.
We can consider &&=as useless for booleans.

因此YES我们可以替换&&&forbool值 ;-)
所以更好地使用&=而不是&&=.
我们可以认为&&=对布尔值没用。

Same for ||=

同为 ||=

operator |=is also less error-pronethan ||=

操作者|=也不太容易出错||=

If a developer wants f2()be called only when f1()returns false, instead of:

如果开发人员只想f2()f1()返回时调用false,而不是:

bool ok = false;
ok ||= f1();
ok ||= f2(); //f2() is called only when f1() returns false
ok ||= f3(); //f3() is called only when f1() or f2() return false
ok ||= f4(); //f4() is called only when ...

I advice the following more understandable alternative:

我建议以下更容易理解的替代方案:

bool ok = false;
if (!ok) ok = f1();
if (!ok) ok = f2();
if (!ok) ok = f3();
if (!ok) ok = f4();
// no comment required here (code is enough understandable)

or if you prefer all in one linestyle:

或者如果您更喜欢一种线条样式:

// this comment is required to explain to developers that 
// f2() is called only when f1() returns false, and so on...
bool ok = f1() || f2() || f3() || f4();