2012-07-09 16 views
60

コード:std :: vectorとstd :: arrayのC++ initializer_listの動作が異なるのはなぜですか?

std::vector<int> x{1,2,3,4}; 
std::array<int, 4> y{{1,2,3,4}}; 

は、なぜ私がのstd ::配列のための二重の中括弧が必要なのでしょうか?

+1

実際に 'std :: array'の2番目の中括弧が必要ですか、それとも警告が出ていますか? 'std :: array y {1,2,3,4};'私のために働く。 – bames53

+3

@ bames53:GCCはそれを編集するのに間違っています。 – Xeo

+10

@Xeo:不正な形式のプログラムを警告でコンパイルするのは間違っていません。 –

答えて

55

std::array<T, N>は集計です:ユーザーが宣言したコンストラクタはありません。std::initializer_listを受け取ったコンシューマもありません。

集計のこの古いスタイルで
std::array<int, 4> y = { { 1, 2, 3, 4 } }; 

:括弧を使用して初期化が集約初期化、集約初期の「古いスタイル」は=を使用していますC.

から継承されたC++の機能を使用して行われます初期化は、余分な括弧が省略されてもよいので、これは、と等価である:

std::array<int, 4> y = { 1, 2, 3, 4 }; 

しかしながら、これらの余分なブレースは、フォームの宣言に」省略されてもよいです"(C++ 11§8.5.1/ 11)、つまり古いスタイル=が使用されている場合に発生します。このルールは、直接のリストの初期化には適用されません。ここでの脚注は次のようになっています。 "リスト初期化の他の使用方法では中括弧は省略できません。

この制限に関する不具合報告があります:CWG defect #1270です。決議案を採用した場合、ブレースエリジオンは、リストの初期化の他の形態に許可され、以下に十分に形成される。

std::array<int, 4> y{ 1, 2, 3, 4 }; 

(欠陥レポートを見つけるためヴィレVoutilainenへの帽子先端。)

+2

私はこれを知らなかった。いいね – chris

+10

"均等な"初期化のために... – Mehrdad

+3

これは、 'array'のために提示される抽象モデルの失敗ですか? –

23

std::vectorはどこことだ(std::arrayは何のコンストラクタを持っていないと{1, 2, 3, 4}がINIT-リストをブレースは、実際にstd::initializer_listとして解釈されていない一方で、std::initializer_list<T>に取るコンストラクタを提供していますが、std::arrayの内側のCスタイルの配列の集計初期化するので第2セットの中かっこは、std::arrayの1つ、th内部のCスタイルのメンバ配列)。

+0

うわー、私はそれを持って、ありがとう:) – Sungmin

関連する問題