C++ primer原文如下:
模板initializer_list是C++11新增的。你可使用初始化列表语法将STL容器初始化为一系列值:
std::vector<double> supplies {99.45, 23.39, 95.19, 1.11};
这将创建一个包含4个元素的容器,并使用列表中的4个值来初始化这些元素。这之所以可行,是因为容器类现在包含将initializer_list<T>作为参数的构造函数。例如,vector<double>包含一个将initializer_list<double>作为参数的构造函数,因此上述声明与下面的代码等价:
std::vector<double> supplies({99.45, 23.39, 95.19, 1.11});
这里显式地将列表指定为构造函数参数。
通常,考虑到C++11新增的通用初始化语法,可使用表示法{}而不是()来调用类构造函数:
shared_ptr<double> pd{new double}; // ok to use {} instead of ()
但如果类也有接受initializer_list作为参数的构造函数,这将带来问题:
std::vector<int> vi{10};
这将调用哪个构造函数呢?
std::vector<int> vi(10); // case A: 10 uninitialized elements
std::vector<int> vi({10}); // case B: 1 element set to 10
答案是,如果类有接受intializer_list作为参数的构造函数,则使用语法{}将调用该构造函数。因此在这个示例中,对应的是情形B。
除非类要用于处理长度不同的列表,否则让它提供接受initializer_list作为参数的构造函数没有意义。例如,对于存储固定数目值的类,你不想提供接受intializer_list作为参数的构造函数。在下面的声明中,类包含三个数据成员,因此没有提供initializer_list作为参数的构造函数:
class Position
{
private:
int x;
int y;
int z;
public:
Position(int xx=0, int yy=0, int zz=0)
: x(xx), y(yy), z(zz) {}
// no initializer_list constructor
......
};
这样,使用语法{}时将调用构造函数Position(int,int,int) :
Position A = {20, -3}; // uses Position{20, -3, 0}
参考文献: