17

二重感嘆符が何をするのかは理解していますが(または理解していると思います)、ランダムなオブジェクトでどのように定義されているのかわかりません。たとえば、以下のコードスニペットでは次のようになります。

Assignment *a;
if (!getAssignment(query, a))
   return false;
hasSolution = !!a;

if (!a)
   return true;

二重感嘆符がどのような値になるかをどのように知ることができますか?言い換えれば、それは常に真に変換されますか?false?または、結果を決定するためのメソッドを実行するなど、その動作を定義できますか(オブジェクトはこの状況でどのように動作するかをどのように知っていますか)?これらすべての感嘆符が進行しているため、このコードについて少し混乱しています。説明をいただければ幸いです。

私が明確であり、感謝していることを願っています。

4

7 に答える 7

22

aポインタです。C ++では、nullptrは無効なポインタとして定義されています。!pointerポインタnullptrtrueに、非nullptrポインタをに変換しfalseます。に!boolean変わります。true_ それは常に機能します。falsefalsetrue

!(!a)それを考えるのに便利な方法です。

于 2012-07-07T12:03:31.817 に答える
11

これを「二重感嘆符」とは考えないでください。一方が他方の結果で実行される2つの別個の演算子と考えてください。

すべてのプリミティブ型で、「機能」します。 !aはと同等a == 0であるため、!!aと同等であり、これは!(a == 0)と同等a != 0です。

ユーザー定義型の場合、オーバーロードしない限りコンパイルされませんoperator !。しかし、明らかに、この場合、動作はほとんど何でもかまいません。

于 2012-07-07T12:05:35.887 に答える
5

!!C++ では単一のトークンではなく、単純に!演算子を 2 回適用することで解決されます。

aクラス型のオブジェクトではなくポインターであるため、オーバー!ロードできません。が null ポインターの場合、そうでない場合に返すtrueように定義されています。afalse

の 2 番目の適用は!、最初の の結果を単純に否定し!ます。

!!aは と同等a != 0です。

于 2012-07-07T12:10:58.880 に答える
3

コードはひどく複雑です。実際には、getAssigmentメソッドが成功したかどうか、および割り当てられたポインターがnullでないかどうかをテストする必要があります。

このコードは、複雑な方法ではありますが、明示性とC ++の強い型付けを採用しようとするのではなく、弱い型付けを利用してテストします。結果として、それは慣用的なC ++ではなく、必要以上に理解するのが難しいです。

!!a特に、 C++では使用しないでください。これは、JavaScriptなどの弱い型の言語で確立されたイディオムであり、値をブール型に強制変換します。しかし、C ++では、これは一般的に使用されていません

hasSolution定義または使用されていないため、コードが何をするのかは明確ではありません。ただし、コードは次のコードと同等であると思われます

Assignment *a;
return getAssignment(query, a) and a == nullptr;

0(C ++ 11より前では、代わりに書く必要がありますnullptr。)

ただし、このコードは依然として悪い設計を示しています。なぜa参照によって渡されるのでしょうか。なぜそれは戻り値ではないのですか?さらに悪いことに、a使用されることはないので、不要です。a本当に不要な場合は、完全に除外する必要があります。必要な場合は、戻り値にする必要があります。つまり、のプロトタイプはgetAssignment次のようになります。

Assignment* getAssignment(the_type_of_query query);

そしてそれは単に次のように使用されるべきです:

Assignment* a = getAssignment(query);

さらに、このコードは実際にメモリの所有権をrawポインタに割り当てているのではないかと思いますa。これは、最新のC++では強く推奨されていません。ポインタを使用しないか、スマートポインタを使用してください。

于 2012-07-07T13:00:34.290 に答える
0
bool result = true; 
result = !!result; // result = true, e.g. !result is false, !!result is !false.
于 2012-07-07T12:02:50.270 に答える
0

「!!」はありません。演算子なので、実際には、ステートメントは次と同等です。

hasSolution = !(!a);

最初に operator!() が式 "a" で呼び出され、次に別の operator!() が結果で呼び出されます。このコードの場合、「a」は代入へのポインタです。C++ は、ポインター型で operator!() を使用するための特別なケースを定義します。ポインターが null の場合は true であり、それ以外の場合は false である bool を返します。つまり、式 (a == 0) と同じです。bool である (!a) の結果に対して operator!() を呼び出すと、単に結果が元に戻されます。つまり、(!a) が false の場合は true を返し、(!a) が true の場合は false を返します。

つまり、(!!a) は (a != 0) と同じ結果を返します。これは、「a」がポインターであるためです。

于 2012-07-07T12:25:20.593 に答える