2011-11-19 10 views
46

の配列私が間違っていなければ、STDを作成することが可能でなければなりません。これらの方法で配列:はstdを使用::初期化リスト

std::array<std::string, 2> strings = { "a", "b" }; 
std::array<std::string, 2> strings({ "a", "b" }); 

そして、まだ、GCC 4.6.1を使用して、私が取得することができませんこれらのいずれかが機能する。コンパイラは単に:

expected primary-expression before ',' token 

と言っていますが、まだ初期化リストはstd :: vectorでうまく動作します。それはどちらですか?私はstd :: arrayが初期化リストを受け入れるべきだと誤っているのですか、あるいはGNU標準C++ライブラリチームがいらっしゃいましたか?

+0

これはクラッシュしました... – Dani

+0

これがうまくいかないかどうかはわかりませんが(私は0xのものは最新ではありません)、バグかどうかは、あなたが 'std: :string'と文字列リテラル。 'std :: string()'で文字列リテラルをラップしようとしましたか? –

+0

@Chris:これはMac OSX 10.6のgcc 4.6.1で動作します。どのコンパイラオプションを使用していますか? – juanchopanza

答えて

72

std::arrayは面白いです。これは基本的に次のように定義されています。

template<typename T, int size> 
struct std::array 
{ 
    T a[size]; 
}; 

これは配列を含む構造体です。初期化子リストを取るコンストラクタはありません。しかし、std::arrayはC++ 11の規則による集約であるため、集約初期化によって作成することができます。標準では、余分な括弧は、この場合には省略されることを示唆していることを

std::array<std::string, 2> strings = {{ "a", "b" }}; 

注:配列内部構造体を初期化し集計するには、中括弧の第2のセットを必要とします。したがって、おそらくGCCのバグです。

+0

標準委員会が目的を果たしましたか? – Dani

+0

標準では、 'std :: array'にイニシャライザリストで動作するコンストラクタが必要なのはなぜですか? –

+6

@PaulManta:それは集約の初期化には適格ではないためです。集約初期化は、配列要素の型に応じてコンパイル時に折り畳むことができます(std :: stringは修飾されません)。イニシャライザリストの初期化は、配列要素の型にかかわらず、ランタイム関数呼び出しでなければなりません。 –

9

受け入れ答えに追加するには:

std::array<char, 2> a1{'a', 'b'}; 
std::array<char, 2> a2 = {'a', 'b'}; 
std::array<char, 2> a3{{'a', 'b'}}; 
std::array<char, 2> a4 = {{'a', 'b'}}; 

GCC 4.6.3(Xubuntuの12.01)上のすべての作業を。しかし、

上記の場合、コンパイルするには二重ブレースが必要です。次のエラーで、単一の括弧の結果とバージョン:

../src/main.cc: In function ‘int main(int, char**)’: 
../src/main.cc:23:17: error: could not convert ‘{'a', 'b'}’ from ‘<brace-enclosed initializer list>’ to ‘std::array<char, 2ul>’ 

私はわからないが、型推論のどのような側面/変換は物事がこのように動作し、かなり、これはGCCの実装の癖がある場合。

関連する問題