16

nullptr_t にデフォルトのコンストラクターがあるかどうかは、C++11 標準からわかりません。言い換えれば、次は有効ですか?:

nullptr_t n; 

GCC と VC++ では上記のコードを使用できますが、clang では使用できません。標準にはデフォルトのコンストラクターがないことを指定するものは何も見つかりません。古いコンパイラのサポートのために nullptr の基本的なフォールバック実装を書いていて、デフォルトのコンストラクタを与える必要があるかどうかを知る必要があるため、これは私にとって重要です。

4

2 に答える 2

17

規格の内容

規格によると(18.2)

nullptr_tは次のように定義されます。

namespace std {
   typedef decltype(nullptr) nullptr_t;
}

nullptr_tが同義語であるタイプには、3.9.1および4.10で説明されている特性があります。

3.9.1は基本的にと同じサイズである必要があると述べておりvoid*、4.10はの変換ルールを指定していますnullptr

編集: 3.9.9はさらにnullptr_t、それがスカラー型であることを明示的に示しています。これは、8.5以降の組み込み型に期待される初期化ルールが適用されることを意味します。

  • Default-initialization(nullptr_t n;)。値はn未定義のままです。Johannes Schaubが正​​しく指摘したように、これは最新バージョンのClangで正常にコンパイルされます。
  • nullptr_t n = nullptr_t();nを0に初期化する値初期化( )。

この動作は、たとえばと同じであるintため、nullptr_tデフォルトで構築可能です。nullptr_tここでの興味深い質問は、未定義の値を持つとはどういう意味ですか?結局のところ、の意味のある可能な値は1つだけです。nullptr_tそれはnullptrです。さらに、型自体は、nullptrリテラルのセマンティクスによってのみ定義されます。これらのセマンティクスは、単一化された値にも適用されますか?

その質問が実際には重要ではない理由

タイプの新しい変数を宣言する必要はありませんnullptr_t。そのタイプの唯一の意味のあるセマンティクスは、nullptrリテラルによってすでに表現されているため、タイプのカスタム変数を使用する場合はいつでも、を使用するnullptr_tこともできますnullptr

実際には何が重要ですか

これに対する唯一の例外は、型の非型テンプレートパラメータをとることができるという事実から来ていますnullptr_t。この場合、nullptr_t4.10で説明されているに変換できる値を知ることは有用です。

ヌルポインタ定数は、整数型の整数型の整数型のprvalue(5.19)であり、ゼロまたは型のprvalueに評価されますstd::nullptr_t。[...]整数型のnullポインタ定数は、型のprvalueに変換できますstd::nullptr_t

これは基本的にあなたが期待することをします:あなたは書くことができます

nullptr_t n = 0;    // correct: 0 is special

だがしかし

nullptr_t n = 42;   // WRONG can't convert int to nullptr_t

gcc4.6とClangSVNの両方がこれを正しく理解しています。

于 2012-03-31T08:22:48.090 に答える
1

は言語自体にnullptr新たに追加されたものですstd::nullptr_tが、名前のない型のエイリアスにすぎません。エイリアスは次のcstddefように宣言されています。

typedef decltype(nullptr) nullptr_t;

nullptr_t言語キーワードではなく typedef であるため、基本型としてリストされていませんが、基本型として動作するように指定されています (たとえば、ポインター型やクラス型としてではありません)。したがって、デフォルトのコンストラクターはありませんが、行ったように変数を宣言できます。あなたの変数は初期化されていません。その用途は何なのか、どのようなエラーメッセージが表示されたのだろうかclang

こちらもご覧ください

于 2012-03-31T08:51:04.337 に答える