13

この回答に触発されて、次の例を試しました:

#include <map>
#include <string>
#include <iostream>

int main()
{
  const std::map< int, std::string > mapping = {
      1, "ONE",
      2, "TWO",
    };

  const auto it = mapping.find( 1 );
  if ( mapping.end() != it )
  {
    std::cout << it->second << std::endl;
  }
  else
  {
    std::cout << "not found!" << std::endl;
  }
}

そしてコンパイルは次のエラーメッセージで失敗しました (g++ 4.6.1):

gh.cpp:11:5: error: could not convert '{1, "ONE", 2, "TWO"}' from '<brace-enclosed initializer list>' to 'const std::map<int, std::basic_string<char> >'

私はそれを修正する方法を知っています:

  const std::map< int, std::string > mapping = {
      {1, "ONE"},
      {2, "TWO"},
    };

しかし、上の例でコンパイルが失敗するのはなぜですか?

4

3 に答える 3

24

マップは非集合体であり、非集合体要素 ( std::pair<key_type, mapped_type>) を含むため、ペアごとに 1 つずつ、初期化子リストでいっぱいの初期化子リストが必要です。

std::pair<int,int> p0{ 1,2 }; // single pair
std::map<int, int> m { { 1,2 } }; // map with one element
std::map<int, int> m { { 1,2 }, { 3,4} }; // map with two elements

ブレース省略のルールは集約に適用されるため、ここでは適用されないことに注意してください。

于 2012-07-31T14:41:23.203 に答える
9

C++11 標準では、ターゲットが集約である場合にのみ中括弧を省略できます。

8.5.1 集計 [dcl.init.aggr]

集約は、ユーザー提供のコンストラクター (12.1)、非静的データ メンバー用のブレースまたはイコール イニシャライザー (9.2)、プライベートまたは保護された非静的データ メンバー (条項 11)、基本クラスなし (条項 10)、および仮想関数なし (10.3)。

...

(パラグラフ11)

フォームの宣言で

T x = { a };

次のように、中かっこは初期化子リストで省略できます。初期化子リストが左中括弧で始まる場合、後続の初期化子節のコンマ区切りリストは、サブ集約のメンバーを初期化します。メンバーより多くの初期化句があるのは誤りです。ただし、部分集合体の初期化子リストが左中括弧で始まらない場合、部分集合体のメンバーを初期化するのに十分なだけの初期化子句がリストから取得されます。残りの初期化句は、現在のサブ集約がメンバーである集約の次のメンバーを初期化するために残されます。

于 2012-07-31T14:52:42.593 に答える
3

C++ を使ってから長い時間が経ちましたが、私が推測するに、std::mapは個々のオブジェクトのセットを期待しており、各オブジェクトにはキーと値のペアが含まれています。

個々のアイテムの単一のリストを持つことは意味がありません。また、読むのも困難です (正確に 2 で割り切れる数のアイテムがあることを確認するため)。

于 2012-07-31T14:41:52.973 に答える