これが機能する理由:
std::pair<int, int> p = {1,2};
std::vector<std::pair<int, int>> vp = { {1,2}, {3,4} };
しかし、これはそうではありませんか?
std::array<int, 2> a = {1,2}; // still ok
std::vector<std::array<int, 2>> va = { {1,2}, {3,4} };
-std=c++0x
でg ++ 4.5.1を使用すると、2行目は次のように失敗します。
エラー:
‘{{1, 2}, {3, 4}}’
を‘std::vector<std::array<int, 2u> >’
に変換できませんでした
ありがとう
残念ながら、std::array
には初期化リストコンストラクターがありません。確かに、noのユーザー定義コンストラクターはありません-この「機能」は、すべてのユーザー定義コンストラクターを省略したC++ 03の残り物です。 Cスタイルのブレースの初期化を有効にする唯一の方法。これは私見ですが、現在の規格の欠陥です。
では、この場合、組み込みの中括弧の初期化が機能しないのはなぜですか?何を見てみましょうstd::array
内部のように見えます:
template <typename T, int i> struct array {
T data[i];
// ...
}
わかりました。つまり、初期化子でdouble中括弧を使用する必要があるという意味ではありません(array
の1つのペア、別のペアdata
メンバーの場合は?
std::array<int, 2> a = { {1, 2} };
C(およびその結果としてC++)には、中括弧の省略に関する特別な規則があり、あいまいさがない限り、内側の中括弧を省略できます。 array
はこの機能を利用して、次のように記述できるようにします。
std::array<int, 2> a = { 1, 2 };
では、なぜ元の投稿の例が機能しないのでしょうか。ブレースの省略は、Cスタイルの集計初期化のコンテキストでのみ許可されるため、ユーザー定義の初期化子リストコンストラクターなど、より複雑なものが含まれる場合は許可されません。
ただし、次のは機能するはずです。
std::vector<std::array<int, 2>> vp = { {{1,2}}, {{3,4}} };
少なくともgcc4.5とgcc4.6ではそうではないという事実は、コンパイラのバグを示しているように思われます。しかし、私はそれについて完全にはわかりません。
この質問はやや関連性があります: initializer_listを使用してメンバー配列を初期化するにはどうすればよいですか?
これは機能します:
std::vector<std::array<int, 2>> va = {
std::array<int, 2>{1,2},
std::array<int, 2>{3,4}
};
さらに深く掘り下げると、std :: pairには初期化子リストを受け取るコンストラクターがあるようですが、std :: arrayにはありません。
std::pair<int, int> p ({1,2}) ; // OK
std::array<int, 2> a ({1,2}) ; // Invalid
しかし今、私は自分の深みから外れています。