web-dev-qa-db-ja.com

です!! C ++でブールに変換する安全な方法?

[この質問は これ に関連していますが、同じではありません。]

特定のタイプの値をブール式として使用しようとすると、警告が表示されます。警告を抑制するのではなく、三項演算子(?:)を使用してブール値に変換することがあります。 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テクニックは本当に同じことをしますか? 3値法よりも安全ですか。この手法は、非整数型でも同様に安全ですか(たとえば、doubleの場合はvoid *またはTを使用して)?

!!tが良いスタイルかどうかは尋ねていません。 t ? true : falseと意味的に異なるかどうかを尋ねています。

49
jwfearn

の引数!演算子と三項演算子の最初の引数はどちらも暗黙的にboolに変換されるため、!!と?:キャストのIMO愚かな冗長な装飾です。私は投票する

b = (t != 0);

暗黙の変換はありません。

82
fizzer

または、これを行うことができます:bool b = (t != 0)

41
Dima

気をつけて!

  • ブール値は、真実と偽りについてです。
  • 整数とは整数のことです。

これらは非常に異なる概念です。

  • 真実と偽りは物事を決定することです。
  • 数はものを数えることについてです。

これらの概念を橋渡しするときは、明示的に行う必要があります。私はディマのバージョンが一番好きです:

b = (t != 0);

そのコードは明確に言っています:2つの数値を比較して真理値をブール値に格納します。

31
edgar.holleis

すべての有効な手法は、すべて同じコードを生成します。

個人的には、警告を無効にして、最もきれいな構文を使用できるようにします。 boolへのキャストは、私が誤って行うことを心配するものではありません。

6
Mike F


はい、安全です。


0はfalseと解釈され、それ以外はすべてtrueです。
したがって、!5は偽として出てきます
!0はtrueとして出力されます
so !! 5はtrueとして出力されます

6
EvilTeach

私は使用しません:

bool b = !!t;

それが最も読みにくい方法です(したがって、維持するのが最も困難です)

その他は状況によって異なります。
ブール式でのみ使用するように変換する場合。

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.

概要:現在のコンテキストに最も意味のあるものを使用してください。
何をしているかを明確にしてみてください

6
Martin York

私はその警告を抑制せず、cキャスト(ブール)を使用して抑制しないことをお勧めします。想定したとおりに変換が呼び出されるとは限りません。

Trueと評価される式とその値のブール値には違いがあります。

両方とも !!そして、三項は慣れてきましたが、boolへのオーバーロードされたキャストで内部型を定義したくない場合は、同じように機能します。

式の値をブール値に割り当てるため、ディマのアプローチも問題ありません。

3
tabdamage

警告が心配な場合は、キャストを強制することもできます:bool b = (bool)t;

2
warren

私は本当に嫌いです!これは、CとC++の最悪のこと、つまり、構文で半分にするにはあまりにも賢い誘惑に駆られます。

bool b(t!= 0); // IMHOの最良の方法です。何が起こっているかを明示的に示します。

2
Jim In Texas

!!コンパクトかもしれませんが、不必要に複雑だと思います。私の意見では、警告を無効にするか、三項演算子を使用する方が良いと思います。

1

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
1
Jay K

私はb =(0!= t)を使用します-少なくともどんな正気な人でも簡単にそれを読むことができます。コードに二重のダングが見られるとしたら、私はかなり驚きます。

0
Alex

!!ブール式を算術式で使用している場合にのみ役立ちます。例:

c = 3 + !!extra; //3 or 4

(スタイルは別の議論です。)必要なのがブール式だけの場合、!!冗長です。書き込み

bool b = !!extra;

以下と同じくらい意味があります:

if (!!extra) { ... }
0
aib

警告を無効にします。

最初に明確にするために書きます。次にプロファイル。次に、必要に応じて速度を最適化します。

0
Jay Bazuzi