が記載されていないのはなぜc++て&&=または||=たboolean値を割り当?

StackOverflow https://stackoverflow.com/questions/2488406

  •  21-09-2019
  •  | 
  •  

質問

はありま "非常に悪いこと" あらゆるトラブル&&=び|=として用いた統語砂糖 bool foo = foo && barbool foo = foo || bar?

役に立ちましたか?

解決

A boolのみC ++でtrue又はfalseであってもよいです。このように、&=|=を使用して(私は特に表記のようになくても)比較的安全です。確かに、それらはむしろ論理演算よりも、ビット操作を実行する(従って、それらは短絡しない)が、これらのビット操作は限り、論理演算を効果的に等価であり、明確に定義されたマッピングに従いますの両方のオペランドがタイプbool のであると。 1

他の人がここで言ったことに反して、

は、C ++でのboolは、2として異なる値を持っていてはいけません。 boolにその値を割り当てる場合、それは標準どおりtrueに変換されます。

boolに無効な値を取得するための唯一の方法は、ポインタにreinterpret_castを使用することです。

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

しかし、いずれにせよ未定義の動作で、このコードの結果から、我々は安全にC ++コードを準拠で、この潜在的な問題を無視することがあります。

<時間>

1 Angewさんのコメントが示すように確かに、これはかなり大きな注意点があります:

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

の理由は、発現が、次いでb & 2に変換バックあるstatic_cast<int>(b) & 2もたらす0、と等価であるように促進整数そのboolを行います。それはoperator &&=の存在は、型の安全性を改善することは事実ですので。

他のヒント

&&&は異なる意味を持っている:最初のオペランドが&&ある場合falseは、第二オペランドを評価しません。すなわち、

のようなもの
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

しかし、事業者 &&=||= うのが論理的になされていること、これらの事業者がエラーが発生しやすいので多くの開発が期待 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
  • ますかける必要は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

この最初のコードが エラーが発生しやすい 多くの開発者がってくださいというふうに思って f2() 常にというもの f1() 返される値です。このように書き bool ok = f1() && f2(); 場所 f2() と呼ばれる場合のみ f1() を返します true.

  • 場合は開い f2() と呼ばれる場合のみ f1() を返します true, このコード上はエラーが発生しやすい.
  • 他の開発者たい f2() する"という), &= 十分:

&=

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

また、いやすいコンパイラの最適化をこの上記のコードより下記の:

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);
}

出力:

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
======================

結論

そのため あり に置き換え && による & のための bool 値;-)
でより良い活用 &= の代わりに &&=.
ができました &&= として役に立たなboolean値を代入します。

同じ ||=

オペレーター |= があります。 エラーが発生しやすい 以上 ||=

が開発したい 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 ...

私の助言を以下のより深くご理解の代替:

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)

または希望の場合は すべてを一つにライン スタイル:

// 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();
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top