C++ 为什么';tc++;有,&;=还是| |=对于布尔人? 是否存在代码< >代码> &代码> >代码> > >代码>作为代码> > BoO-Foo= Fo&& Bar < /C> >和 Boo-Foo= Foo[f]条
a >代码> Boo< <代码> > C++中只能是代码>真< /> >或<代码> false <代码>。因此,使用C++ 为什么';tc++;有,&;=还是| |=对于布尔人? 是否存在代码< >代码> &代码> >代码> > >代码>作为代码> > BoO-Foo= Fo&& Bar < /C> >和 Boo-Foo= Foo[f]条,c++,boolean-operations,C++,Boolean Operations,a >代码> Boo< > C++中只能是代码>真< /> >或 false 。因此,使用&=和|=是相对安全的(尽管我并不特别喜欢这种符号)。诚然,它们将执行位运算而不是逻辑运算(因此不会短路),但这些位运算遵循定义良好的映射,这实际上相当于逻辑运算,,只要两个操作数的类型都是bool。1 与其他人所说的相反,C++中的布尔O/COD>绝对不能有不同的值,如 2 。将该值指定给bool时,将根据标准将其转换为true 将无效值放入bool的唯一方法是在指针上使用reinterpret\u c
&=
和|=
是相对安全的(尽管我并不特别喜欢这种符号)。诚然,它们将执行位运算而不是逻辑运算(因此不会短路),但这些位运算遵循定义良好的映射,这实际上相当于逻辑运算,,只要两个操作数的类型都是bool
。1
<>与其他人所说的相反,C++中的<代码>布尔O/COD>绝对不能有不同的值,如<代码> 2 <代码>。将该值指定给bool
时,将根据标准将其转换为true
将无效值放入bool
的唯一方法是在指针上使用reinterpret\u cast
:
int i = 2;
bool b = *reinterpret_cast<bool*>(&i);
b |= true; // MAY yield 3 (but doesn’t on my PC!)
原因是
b&2
执行整数提升,这样表达式就相当于static_cast(b)&2
,结果是0
,然后将其转换回bool
。因此,确实存在一个<代码>运算符& &=//> >将提高类型安全性。 < p> Auth>代码> BOOL<代码>,只能是C++中的代码>真< /COD>或<代码> false < /C>。因此,使用&=
和|=
是相对安全的(尽管我并不特别喜欢这种符号)。诚然,它们将执行位运算而不是逻辑运算(因此不会短路),但这些位运算遵循定义良好的映射,这实际上相当于逻辑运算,,只要两个操作数的类型都是bool
。1
<>与其他人所说的相反,C++中的<代码>布尔O/COD>绝对不能有不同的值,如<代码> 2 <代码>。将该值指定给bool
时,将根据标准将其转换为true
将无效值放入bool
的唯一方法是在指针上使用reinterpret\u cast
:
int i = 2;
bool b = *reinterpret_cast<bool*>(&i);
b |= true; // MAY yield 3 (but doesn’t on my PC!)
原因是
b&2
执行整数提升,这样表达式就相当于static_cast(b)&2
,结果是0
,然后将其转换回bool
。因此,运算符&&
的存在确实会提高类型安全性。&&
和&
具有不同的语义:&
如果第一个操作数为false,则不会计算第二个操作数。i、 例如
flag = (ptr != NULL) && (ptr->member > 3);
是安全的,但是
flag = (ptr != NULL) & (ptr->member > 3);
不是,尽管两个操作数的类型都是bool
这同样适用于&=
和|=
:
flag = CheckFileExists();
flag = flag && CheckFileReadable();
flag = flag && CheckFileContents();
其行为将不同于:
flag = CheckFileExists();
flag &= CheckFileReadable();
flag &= CheckFileContents();
&
和&
具有不同的语义:&
如果第一个操作数为false,则不会计算第二个操作数。i、 例如
flag = (ptr != NULL) && (ptr->member > 3);
是安全的,但是
flag = (ptr != NULL) & (ptr->member > 3);
不是,尽管两个操作数的类型都是bool
这同样适用于&=
和|=
:
flag = CheckFileExists();
flag = flag && CheckFileReadable();
flag = flag && CheckFileContents();
其行为将不同于:
flag = CheckFileExists();
flag &= CheckFileReadable();
flag &= CheckFileContents();
简短回答
所有运算符+=
,-=
,*=
,/=
,&=
,|=
。。。是算术运算,并提供相同的期望值:
x &= foo() // We expect foo() be called whatever the value of x
但是,操作符&&=
和|124;=
是逻辑的,而且这些操作符可能容易出错,因为许多开发人员希望总是在x&&=foo()
中调用foo()
- 我们真的需要使C/C++更加复杂,才能获得
x=x&&foo()的快捷方式吗
- 我们真的想让这句晦涩难懂的语句变得更加模糊吗
x=x&&foo()
?
或者我们想要编写有意义的代码,比如if(x)x=foo()代码>
长话短说
&&=
如果操作员可用,则此代码:
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
相当于:
bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true
第一个代码容易出错,因为许多开发人员认为无论返回值是什么,f1()
总是调用f2()
。这就像写bool ok=f1()&&f2()
wheref2()
仅在f1()
返回true
时调用
- 如果开发人员实际上希望仅当
f1()
返回true
时调用f2()
,那么上面的第二个代码就不太容易出错
- 否则(开发人员希望总是调用
f2()
,&=
就足够了:
&=
此外,编译器优化上述代码比优化以下代码更容易:
bool ok = true;
if (!f1()) ok = false;
if (!f2()) ok = false; //f2() always called
比较&
和&
我们可能想知道,当应用于bool
值时,运算符&&
和&
是否给出相同的结果
让我们检查下面的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);
}
结论
因此,是我们可以将&
替换为&
,用于bool
值;-)
因此,最好使用&=
而不是&&=
我们可以考虑<代码> & & = /代码>对布尔代数没有用。
与| |=
运算符|=
也比|=
更不容易出错
如果开发人员希望仅在f1()
返回false
时调用f2()
,而不是:
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 ...
我建议以下更容易理解的替代方案:
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)
或者,如果您更喜欢“一体式”样式:
简短回答
所有运算符+=
,-=
,*=
,/=
,&=