4

この例のクラスを考えると:

template<typename T>
class ExampleContainer
{
private:        
  std::map<T, int> _objects;
  int _sum;

public:
  ExampleContainer()
    : _objects(), _sum(0)
  {
  }

  void Add(T obj, int add)
  {
    _objects[obj] = add; // yes this is bad, but it's an example.
    _sum += add;
  }
};

このように使用できるようにするために必要なもの:

ExampleContainer<char*> _rarities =
{
  { "One", 600 },
  { "Two", 200 },
  { "Three", 50 },
  { "Four", 10 },
  { "Five", 1 },
};

std::map をすでにそのように初期化できるので、何とか可能であるに違いないことはわかっています。

ご回答ありがとうございます。

4

1 に答える 1

11

を受け入れるコンストラクターをクラスに追加するだけstd::initializer_listですExampleContainer

ExampleContainer(std::initializer_list<typename std::map<T, int>::value_type> l)
    :
    _objects(l)
{
}

これは、次の場合のように、中括弧を使用してオブジェクトを初期化するたびに呼び出されます。

ExampleContainer<char*> _rarities =
{
    ...
};

このようにして、中括弧内の各エントリが初期化子リストの要素になります。

ここでの初期化子リストの基になる型は であるため、その型のstd::map<T, int>::value_type一時オブジェクトは、指定した値から構築されます。

ExampleContainer<char*> _rarities =
{
    { "One", 600 },     // Each of these entires will cause the creation of
    { "Two", 200 },     // a temporary object of type:
    { "Three", 50 },    //     std::pair<char* const, int>
    { "Four", 10 },     // that will become an element of the initializer
    { "Five", 1 },      // list received by the constructor.
};

また、文字列リテラルから への変換は C++03 では非推奨であり、C++11 では無効であることに注意してくださいchar*(文字リテラルchar const[]C++11 で型を持ちます)。_raritiesしたがって、代わりに変数に型を指定することをお勧めしますExampleContainer<char const*>(C 配列型はポインター型に減衰します)。

アップデート:

コメントで @LightnessRacesInOrbit が正しく指摘しているように、コンテナーで文字列リテラルのみを使用しない場合、このアプローチは危険です (これは、例から推測したものですが、実際には何も意味しません)。代わりに使用することをお勧めします(したがって、 としてstd::string宣言する必要があります)。_raritiesExampleContainer<std::string>

于 2013-02-17T17:17:42.520 に答える