1. ホーム
  2. c++

[解決済み] std::vector と std::array の C++ initializer_list の動作はなぜ違うのですか?

2023-06-26 18:43:29

質問

コードを入力してください。

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

なぜstd::arrayには二重中括弧が必要なのですか?

どのように解決するのですか?

std::array<T, N> は集合体です: これはユーザが宣言したコンストラクタを持ちません。 std::initializer_list . 中括弧を使った初期化は 集合的初期化 というC++の機能を継承しています.

凝集体初期化の "古いスタイル" では、凝集体初期化のために = :

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

この古いスタイルの集合体初期化では、余分な中括弧は省略されることがあるので、これは次のように等価である。

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

しかし、これらの余分な中括弧は、以下の形式の宣言においてのみ省略することができます。 T x = { a }; (C++11 §8.5.1/11) つまり、旧スタイルの = が使用される場合です。 中括弧の削除を許可するこのルールは、リストの直接初期化には適用されません。 この脚注には、「リスト初期化の他の用途では、中括弧を省略することはできません」と書かれています。

この制限に関する不具合報告があります。 CWG defect #1270 . 提案された解決策が採用されると、他の形式のリスト初期化でも brace elision が許可され、以下のように整形されるようになります。

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

(この不具合報告を見つけたVille Voutilainenに脱帽)