1.列表初始化
注意和初始化列表区分开来,在 C++ 98
中允许使用花括号对数组或者结构体元素进行统一的初始值设定。
struct Point
{int _x;int _y;
};int main()
{int array1[] = { 1, 2, 3, 4, 5 };int array2[5] = { 0 };Point p = { 1, 2 };return 0;
}
而 C++ 11
扩大了用花括号列表初始化的使用范围,可以用于所有内置类型和用户自定义类型。并且在使用列表初始化时,可以添加等号,也可以不添加。
struct Point
{int _x;int _y;
};
int main()
{int x1 = 1;int x2{ 2 };int array1[]{ 1, 2, 3, 4, 5 };int array2[5]{ 0 };Point p{ 1, 2 };//列表初始化也可用于 new 表达式中int* pa = new int[4]{ 0 };return 0;
}
并且期间还有可能发生构造调用。
int main()
{Date d1 { 2023, 5, 6 };//单纯调用构造Date d2 = { 2012, 3, 10 };//构造加拷贝构造,有可能发生优化(如果构造函数加上 explicit 这句话就非法了)return 0;
}
那么使用列表初始化构造一个容器(比如:vector
和 list
)是怎么做到的呢?实际上,花括号内的常量数组会被识别为一个新的类类型:initializer_list
。
#include <iostream>
#include <initializer_list>
int main()
{auto il = { 1,2,3 };std::cout << typeid(il).name() << '\n';return 0;
}
并且该对象的数据在常量区存储,无法使用迭代器修改内部的值。
2.容器的列表初始化接口
C++ 11
新增加了一些容器:array
、forward_list
、unordered_set
、unordered_map
,并且增加了一些新方法,例如:容器都支持使用列表初始化的构造函数,这使得所有的容器可以更加方便设置初始值。