std::initializer_list
は中括弧で囲まれた初期化リストからコンパイラーによって構築され、このリストのサイズはコンパイル時定数でなければなりません。
では、なぜ委員会はテンプレートの引数からサイズを省略することにしたのでしょうか。これにより、一部の最適化が妨げられ、一部の処理が不可能になる可能性があります(std::array
からの初期化std::initializer_list
)。
std::initializer_list
は中括弧で囲まれた初期化リストからコンパイラーによって構築され、このリストのサイズはコンパイル時定数でなければなりません。
では、なぜ委員会はテンプレートの引数からサイズを省略することにしたのでしょうか。これにより、一部の最適化が妨げられ、一部の処理が不可能になる可能性があります(std::array
からの初期化std::initializer_list
)。
initializer_list
がとして定義されている場合std::initializer_list<type, size>
、具体的なinitializer_list<type>
型である、をとる関数はtype
、そのリストのサイズに基づくテンプレート関数である必要があります。initializer_list
または、ユーザーが特定のタイプとサイズのを渡すことを要求する必要があります。
これらの両方はかなり受け入れられません。誰もがすべてのコードをテンプレートとして作成するわけではありません。
std::array
braced-init-listからを初期化できます({}
中央に何かがあります)。しかし、それはと同じことではありませんstd::intiializer_list
。array
クラスは集約型です。これは、パブリック配列である単一の要素を含む構造体です。したがって、準拠する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の動作は次のようになります。int
0
int
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
既存のシステムの利点の1つはinitializer_list
、DLLからを取得する関数をエクスポートできることです。サイズに基づいてテンプレート化されている場合は、ソースとして出荷する必要があります。