ビットレベル演算子のデメリット。
あなたが尋ねる:
「ビット演算子を使用しない何らかの理由がある&
、|
と^
のために、 『C ++でのブール値』の値?」
はい、論理演算子で、ハイレベルのブール演算子を内蔵!
、&&
および||
、以下の利点があります。
保証の引数の変換にbool
、すなわちへ0
と1
序数値。
最終結果がわかるとすぐに式の評価が停止する、保証された短絡評価。
これは、True、False、およびIndeterminateのツリー値ロジックとして解釈できます。
読み取り可能なテキスト同等物not
、and
およびor
私はそれらを自分で使用していない場合でも、。
リーダーとしてのコメントでアンチモンノートもbitlevel事業者は、すなわち、代替トークンを持ってbitand
、bitor
、xor
とcompl
、私の意見では、これらは、より読みにくくしているand
、or
とnot
。
簡単に言えば、高レベルの演算子のこのような利点はそれぞれ、ビットレベルの演算子の欠点です。
特に、ビット演算子には0/1への引数変換がないため、たとえば1 & 2
→ 0
、while 1 && 2
→ true
。が得られます。また^
、ビット単位の排他的論理和は、このように誤動作する可能性があります。ブール値1と2は同じ、つまりtrue
、と見なされますが、ビットパターンと見なされます。
論理的な表現方法/またはC ++で。
次に、質問の背景を少し説明します。
「2つの条件のいずれか1つを真(XOR)にしたい状況に遭遇することがあるので、^演算子を条件式に挿入するだけです。」
そうですね、ビット演算子は論理演算子よりも優先されます。これは特に、次のような混合式では
a && b ^ c
おそらく予想外の結果が得られます a && (b ^ c)
。
代わりにただ書く
(a && b) != c
あなたが意味することをより簡潔に表現する。
複数の引数の場合、またはその両方の場合、ジョブを実行する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
&=
ブール結果を累積するために使用します。
あなたはさらに詳しく説明します、
「私はまた、時々 、ブール値を蓄積する必要があり、&=
かつ|=?
、非常に便利です。」
さて、これはそれぞれすべてまたはいずれかの条件が満たされているかどうかをチェックすることに対応し、ド・モルガンの法則は一方から他方に移動する方法を示しています。つまり、そのうちの1つだけが必要です。あなたは原則*=
としてとして使用することができます&&=
演算子(古き良きジョージ・ブールが発見したように、論理ANDは乗算として非常に簡単に表現できます)が、それはコードのメンテナを困惑させ、おそらく誤解を招くと思います。
また考慮してください:
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での出力:
true
false
結果が異なる理由は、ビットレベル&=
がbool
右側の引数のへの変換を提供しないためです。
それで、あなたはこれらの結果の&=
どれをあなたの使用に望みますか?
前者の場合はtrue
、演算子(上記のように)または名前付き関数を定義するか、右側の式の明示的な変換を使用するか、更新を完全に記述します。