如何为我自己的集合类启用包含大括号的初始值设定项列表

How to enable brace enclosed initializer lists for my own collection class?

本文关键字:列表 我自己 自己的 集合类 包含大 启用      更新时间:2023-10-16

给定以下示例类:

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了。

提前感谢您的回答。

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

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.
};

另外请注意,从字符串文字到char*的转换在C++03中是不赞成的,在C++11中是无效的(字符串文字在C++11中的类型为char const[])。因此,您可能希望将变量_rarities的类型改为ExampleContainer<char const*>(C数组类型衰减为指针类型)。

更新:

正如@LightnessRacesInOrbit在评论中正确指出的那样,如果你不打算在容器中只使用字符串文字,这种方法是危险的(这是我从你的例子中假设的,但事实上没有任何暗示)。最好使用std::string(因此应该将_rarities声明为ExampleContainer<std::string>)。