29

このSOの質問の議論中に出てきた質問として:

おそらくN3471constexpr std::initializer_listを使用して、オブジェクトを宣言することは合法ですか? 例:

constexpr std::initializer_list<int> my_list{};

合法ではないかもしれないと思う理由:initializer_listリテラル型でなければなりません。しかし、それがリテラル型であるという保証はありますか?

N3485 からの引用。

[dcl.constexpr]/9:

オブジェクト宣言で使用される constexpr 指定子は、オブジェクトを const として宣言します。そのようなオブジェクトはリテラル型を持ち、初期化されます。

リテラル型の要件、[basic.types]/10、サブブレット クラス型:

  • 次のすべてのプロパティを持つクラス タイプ (条項 9):
    • 自明なデストラクタがあり、
    • 非静的データ メンバー (存在する場合) のブレースまたはイコール初期化子内のすべてのコンストラクター呼び出しと完全式は、定数式 (5.19) です。
    • 集約型 (8.5.1) であるか、またはコピーまたは移動コンストラクターではない少なくとも 1 つの constexpr コンストラクターまたはコンストラクター テンプレートを持ち、かつ
    • その非静的データ メンバーと基本クラスはすべて、非揮発性リテラル型です。

ボーナスポイント;)

constexpr std::initializer_list<int> my_list = {1,2,3,4,5};

合法です(参照あり)。これは上記の+ [dcl.init.list]/5でカバーされていると思いますが

4

1 に答える 1

11

更新: CWG DR 1684の決議により、以下に引用されている要件が削除された後、状況は少し複雑になりました。std-discussion メーリング リストのこのディスカッションと、関連する質問Why doesn't `std::initializer_list` defined as aliteral type? で、さらに詳しい情報を見つけることができます。


[decl.constexpr]/8:

コンストラクターではない非静的メンバー関数の constexpr 指定子は、そのメンバー関数が const であることを宣言します (9.3.1)。[...] その関数がメンバーであるクラスは、リテラル型 (3.9) でなければなりません。

したがって、N3471 保証の変更はstd::initializer_listリテラル型になります。


constexprctor だけがリテラル型である必要はないことに注意してstd::initializer_listください。[dcl.constexpr]/4+8 を参照してください。補足: ctor を持つ非リテラル型のオブジェクトは、定数の初期化[basic.start.init]/2] (動的初期化の前に実行される静的初期化constexprの一部)中に初期化できます。

于 2013-04-17T18:25:49.047 に答える