如何为我自己的集合类启用大括号括起初始化列表?

xNi*_*ogg 4 c++ collections std initializer-list c++11

鉴于此示例类:

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;
  }
};
Run Code Online (Sandbox Code Playgroud)

需要什么才能像这样使用它:

ExampleContainer<char*> _rarities =
{
  { "One", 600 },
  { "Two", 200 },
  { "Three", 50 },
  { "Four", 10 },
  { "Five", 1 },
};
Run Code Online (Sandbox Code Playgroud)

我知道它必须以某种方式可能,因为我可以初始化一个像这样的std :: map.

提前感谢您的任何答案.

And*_*owl 11

只需添加一个构造函数接受一个std::initializer_list你的ExampleContainer类:

ExampleContainer(std::initializer_list<typename std::map<T, int>::value_type> l)
    :
    _objects(l)
{
}
Run Code Online (Sandbox Code Playgroud)

每次使用花括号初始化对象时都会调用此方法,如下例所示:

ExampleContainer<char*> _rarities =
{
    ...
};
Run Code Online (Sandbox Code Playgroud)

这样,花括号内的每个条目都将成为初始化列表的一个元素.

由于此处初始化列表的基础类型是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.
};
Run Code Online (Sandbox Code Playgroud)

另请注意,从字符串文字转换char*为在C++ 03中弃用,在C++ 11中无效(字符串文字char const[]在C++ 11中具有类型).因此,您可能希望为变量赋予_rarities类型ExampleContainer<char const*>(C数组类型衰减为指针类型).

更新:

正如@LightnessRacesInOrbit在评论中正确指出的那样,如果你不打算在你的容器中使用字符串文字,这种方法是危险的(这是我从你的例子中假设的东西,但实际上并没有暗示它).使用它是一个更好的主意std::string(所以你应该声明_raritiesExampleContainer<std::string>).