C++ 引入了统一初始化(uniform initialization)的概念,意味着程序员可以使用一个通用的句法去进行任意的初始化。可以使用大括号初始化器用于任何类型(可以使用等号,也可以不使用),这是一种通用的初始化语法。
使用 {} 初始化单值变量
这个句法使用 {} 来进行统一初始化,如下所示:
int hamburgers = {24}; // set hamburgers to 24
int emus{7}; // set emus to 7(使用这种方式时,可以使用等号,也可以不使用)
int rocs = {}; // set rocs to 0
int psychics{}; // set pshchics to 0
使用 {} 初始化复合类型变量
int values[]{1,2,3} ;
vector<int> v{2,3,4,5,6};
vector<string> cities{
"Berlin", "New York", "London", "Braunschweig"};
这其实是利用一个事实:编译器一看到 {} 便做出一个 initializer_list<T>,它关联到一个array<T, n>(标准库提供的一个容器)。调用函数(例如构造函数)时该 array 内的元素会被编译器分解逐一赋给函数。
但如果函数的参数是initializer_list<T>,调用者却不能给数个T参数然后以为它们会被自动转为一个initializer_list<T>传入。如果函数的入参是、initializer_list<T>,那么 在调用函数的时候就要传入{T1, T2, T3,...},不能传入T1, T2, T3,...,然后让编译器去把这些参数自动转换为一个initializer_list<T>。
以上两段可以理解为编译器会自动把{}看做是一个initializer_list<T>,而且可以分解initializer_list<T>,也就是可以把{}分解为一堆元素。但是不会把一堆元素自动转换成initializer_list<T>,也就是不会自动给一堆参数加{}。
#include <iostream>
using namespace std;
class P
{
public:
explicit P(int a, int b)
{
cout << "P (int a, int b), a = " << a << ", b = " << b << endl;
}
P(initializer_list<int> initList)
{
cout << "P(initializer_list<int> initList), values = ";
for (auto i : initList)
{
cout << i << ", ";
}
cout << endl;
}
};
int main()
{
P p1(1,2);
P p2{1,2};
P p3{1,2,3};
P p4={3,4,5}; // 调用构造函数
// P p5(1,2,3,5); // 会报错
}
执行结果如下: