8

次のコードを3つのコンパイラでテストし、エラー、警告、およびokという3つの異なる結果が得られました。nullptr_tからboolへの変換:有効かどうか?

  • GCC(5.3):警告: 'ブール' にnullptr定数の暗黙的な変換エラー: 'CONSTシング&'
  • クラン(3.8)への無効なユーザー定義の変換 'のstd :: nullptr_t'
  • MSVC(14.1):エラーなし、正しいコンパイラ警告なし

?私はそれがポインタータイプとboolの間の些細な変換であることを知っています。しかし、std::nullptr_tboolは何ですか?

(最後に、クランとMSVCの両方のコードで微細である。クランが積極的にもう少し冗長である。)

struct Thing 
{ 
    Thing(bool) {} 
}; 

void addThing(const Thing&){} 

int main() 
{ 
    addThing(nullptr); // warning or error on this line 
} 

答えて

8

これは無効です。 boolean conversionsの規則に従って:

A prvalue of type std::nullptr_t , including nullptr , can be converted to a prvalue of type bool in context of direct-initialization. The resulting value is false .

変換のみによって、関数の引数を渡すためのケースを含むdirect-initializationはなく、copy-intialization、許可されている標準からの引用、§7.14/1 Boolean conversions [conv.bool]

For direct-initialization, a prvalue of type std​::​nullptr_­t can be converted to a prvalue of type bool ; the resulting value is false .

値。例えば

bool b1 = nullptr; // invalid 
bool b2 {nullptr}; // valid 

だからGCCは正しいです。しかし、クラングも間違っていません。この規格では、プログラムの作成時にコンパイラーが「診断を発行する」ことだけが要求されるため、何かが起きた後、何かが起こる可能性があることを伝える必要があります。

を参照してください。Does the C++ standard specify that for some cases the compiling should fail with an error?

+0

ここでは論理的に矛盾していますか? (答えではない)。私はそれが他の理由で強制されたと確信していますが、これは実際には '_cast'演算子がなくてもどちらもうまくいかないケースとして私を襲います。 –

+1

@BrettHale私の解釈は、 'nullptr'は(ポインタ型とメンバ型へのポインタの)nullポインタに暗黙的に変換できるということです。 'bool'への変換は明示的でなければならないが、他のポインタの一貫性のためには許されている。 – songyuanyao

+1

@Brett Hale私はそれが矛盾しているとは思わない。明示的にコンストラクタを呼び出すと、驚きの驚きは、明示的にマークされたコンストラクタを呼び出します。これは、静的キャストが行うことの1つです。これらは基本型なので、文字通りコンストラクタはありませんが、アイデアは同じです。 –

関連する問題