17

std::initializer_listは中括弧で囲まれた初期化リストからコンパイラーによって構築され、このリストのサイズはコンパイル時定数でなければなりません。

では、なぜ委員会はテンプレートの引数からサイズを省略することにしたのでしょうか。これにより、一部の最適化が妨げられ、一部の処理が不可能になる可能性があります(std::arrayからの初期化std::initializer_list)。

4

2 に答える 2

15

initializer_listがとして定義されている場合std::initializer_list<type, size>、具体的initializer_list<type>型である、をとる関数はtype、そのリストのサイズに基づくテンプレート関数である必要があります。initializer_listまたは、ユーザーが特定のタイプとサイズのを渡すことを要求する必要があります。

これらの両方はかなり受け入れられません。誰もがすべてのコードをテンプレートとして作成するわけではありません。

std::arraybraced-init-listからを初期化できます({}中央に何かがあります)。しかし、それはと同じことではありませんstd::intiializer_listarrayクラスは集約型です。これは、パブリック配列である単一の要素を含む構造体です。したがって、準拠するC ++ 11実装では、これをコンパイルする必要があります。

std::array<int, 3> myArray = {1, 3, 5};

ただし、{1, 3, 5}std::initializer_listオブジェクトではありません。これは単なるbraced-init-listであり、適切な型を初期化するために使用できます。

集合体にはコンストラクターがないため、オブジェクトを集合体のコンストラクターに渡すことはできませんが、配列を含む構造体の場合と同様std::initializer_listに、braced-init-listを使用して集合体の初期化を呼び出してを初期化できます。std::array

aとbraced-init-listの違いは、anとリテラルstd::initializer_listの違いに少し似ています。オブジェクトを暗黙的にポインタ型に変換することは(通常)合法ではありませんが、整数リテラル0をポインタ型に暗黙的に変換することは合法です。braced-init-listsの動作は次のようになります。int0int

int i = 0;    //Legal
void *j = 0;  //Legal
void *k = i;  //Not legal

std::array<int, 3> myArray = {1, 3, 5};             //Legal
std::initializer_list<int> myInitList = {1, 3, 5};  //Legal
std::array<int, 3> myArray = myInitList;            //Not legal
于 2011-08-18T18:31:10.817 に答える
8

既存のシステムの利点の1つはinitializer_list、DLLからを取得する関数をエクスポートできることです。サイズに基づいてテンプレート化されている場合は、ソースとして出荷する必要があります。

于 2011-08-18T13:53:06.053 に答える