std::initializer_list

std::initializer_list

std::initializer_list<T>是C++11引入的新特性,在C++11之前我们可以这样初始化一个数组,但要初始化容器类却无法一行代码完成:

1
2
3
4
5
6
int arr[]= {1,2,3,4,5};

// Old Way to initialize a vector
std::vector<int> vec1;
for(int i = 0; i < 5; i++)
vec1.push_back(i);

而在C++11我们可以这样实现:

1
std::vector<int> vec= {1,2,3,4,5}; // Compile Error before C++ 11

对于std::initializer_list<T>,我们可以创建一个这样的对象:

1
std::initialzer_list<int> data = {1,2,4,5};

当编译器看到这样的形式时{a,b,c},它会自动创建一个这样的对象std::initialzer_list<T>,另外像vector或者list之类的容器,也实现了一个参数化的构造器:

1
2
3
4
vector<T>::vector<T>(initializer_list<T>  elements)
{
......
}

Using std::initializer_list in constructors to initialize member variables

我们也可以用std::initializer_list<T>去初始化成员变量,假设我们有一个这样的类:

1
2
3
4
5
6
7
8
9
10
11
12
class Point {
int mX;
int mY;
int mZ;
public:
Point(int a, int b, int c) :
mX(a), mY(b), mZ(c) {
}
void display() {
std::cout << "(" << mX << "," << mY << "," << mZ << ")\n";
}
};

我们可以直接传递一个initializer_list作为参数:

1
Point pointobj({1,2,3]});

但如果我们有一个构造器,其参数恰好就是std::initializer_list<T>,那么它就会调用该构造起,而不是调用以上三参数形式的构造起。

How to Initialize a map in one line using initialzer_list ?

同样的,我们也可以用std::initialzer_list<T>初始化一个map:

1
2
3
4
std::map<std::string, int> mapOfMarks = {
{"Riti",2},
{"Jack",4}
};

相对应的,编译器会在内部创建这样的一个对象:

1
2
3
4
std::initializer_list<std::pair<const std::string, int> > = {
{"Riti",2},
{"Jack",4}
};