!! C ++でboolに変換する安全な方法は?
-
03-07-2019 - |
質問
[この質問は、これ。]
特定のタイプの値をブール式として使用しようとすると、警告が表示されます。警告を抑制するのではなく、三項演算子(?:
)を使用してブールに変換することがあります。 2つのnot演算子( !!
)を使用しても同じことをするようです。
これが私が言っていることです:
typedef long T; // similar warning with void * or double
T t = 0;
bool b = t; // performance warning: forcing 'long' value to 'bool'
b = t ? true : false; // ok
b = !!t; // any different?
では、double-notテクニックは実際に同じことを行いますか?三進法よりも安全ですか?この手法は、非整数型(たとえば、 T
の void *
または double
)でも同様に安全ですか?
!! t
が良いスタイルかどうかは尋ねません。私はそれが tと意味的に異なるかどうか尋ねていますか? true:false
。
解決
!の引数演算子と三項演算子の最初の引数は両方とも暗黙的にブールに変換されるため、!!および?:キャストのIMOの愚かな冗長装飾です。に投票します
b = (t != 0);
暗黙的な変換はありません。
他のヒント
あるいは、これを行うことができます: bool b =(t!= 0)
注意!
- ブール値とは、真実と偽りに関するものです。
- 整数は整数です。
これらは非常に明確な概念です:
- 真実と虚偽は、物事を決めることです。
- 数字はものを数えることです。
これらの概念を橋渡しする場合、明示的に行う必要があります。私はDimaのバージョンが一番好きです:
b =(t!= 0);
そのコードは次のように明確に述べています。2つの数値を比較し、真理値をブール値で保存します。
すべての有効な手法、すべてが同じコードを生成します。
個人的には、最もクリーンな構文を使用できるように、警告を無効にします。ブールへのキャストは、誤って行うことについて心配しているものではありません。
はい、安全です。
0はfalseと解釈され、他のすべてはtrueと解釈され、
したがって、!5は偽として出てきます。
!0はtrueとして出力されます
だから!! 5が本当だと思います
私は使用しません:
bool b = !!t;
これは最も読みにくい方法です(したがって、維持するのが最も困難です)
その他は状況に依存します。
bool式のみで使用するように変換する場合。
bool b = t ? true : false;
if (b)
{
doSomething();
}
その後、言語にそれをさせます:
if (t)
{
doSomething();
}
実際にブール値を保存している場合。それからまず、キャストを必要とする最初の場所に長い理由があるのだろうかと思います。 longとboolの値が必要だと仮定して、状況に応じて次のすべてを検討します。
bool b = t ? true : false; // Short and too the point.
// But not everybody groks this especially beginners.
bool b = (t != 0); // Gives the exact meaning of what you want to do.
bool b = static_cast<bool>(t); // Implies that t has no semantic meaning
// except as a bool in this context.
概要:
現在のコンテキストに最も意味のあるものを使用します。
あなたが何をしているのかをはっきりさせてください
その警告を抑制しないこと、およびcキャスト(ブール)を使用してそれを抑制することはお勧めしません。想定どおりに変換が呼び出されるとは限りません。
trueと評価される式とその値のブール値には違いがあります。
両方!!そして、三項式は慣れますが、boolへのオーバーロードキャストで内部型を定義したくない場合、同様に仕事をします。
Dimaのアプローチも、式の値をブールに割り当てるため、問題ありません。
警告が気になる場合は、キャストを強制することもできます: bool b =(bool)t;
本当に大嫌い!! t !!!!!!。これはCとC ++の最悪の部分をひっくり返します。構文が半分になりすぎるという誘惑です。
bool b(t!= 0); //私見の最良の方法であり、何が起こっているかを明示的に示します。
!!コンパクトかもしれませんが、不必要に複雑だと思います。私の意見では、警告を無効にするか、三項演算子を使用する方が良いでしょう。
b =(0!= t)を使用します-少なくとも正気な人なら誰でも簡単に読むことができます。コードに二重のダングが表示される場合、私は非常に驚くでしょう。
警告を無効にします。
最初に明確にするために書きます。次にプロファイル。その後、必要に応じて速度を最適化します。
!!算術式でブール式を使用している場合にのみ有用です。例:
c = 3 + !!extra; //3 or 4
(スタイルは異なる議論です。)必要なのはブール式だけである場合、!!冗長です。書く
bool b = !!extra;
次と同じ意味があります:
if (!!extra) { ... }
0との比較はあまりうまくいきません。 どっちが戻ってくるのか-なぜ!!対三元?
class foo { public: explicit operator bool () ; };
foo f;
auto a = f != 0; // invalid operands to binary expression ('foo' and 'int')
auto b = f ? true : false; // ok
auto c = !!f; // ok
使用することをお勧めします
if(x!= 0)
または
if(x!= NULL)
if(x)の代わり;より理解しやすく、読みやすくなっています。
doubleは、私にとって面白くなく、デバッグコードでは最適化されたコードとは大きく異なります。
あなたが好きなら!!いつでもマクロ化できます。
#define LONGTOBOOL(x) (!!(x))
(さておき、三項演算子は私がこれらの場合に好むものです)
bool b = tを使用し、コンパイル警告を残して、この特定の行の安全性についてコメントします。警告を無効にすると、コードの別の部分であなたに噛み付く可能性があります。