列表初始化:用 {} 可以初始化一切
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;
}
1. C++11 中 {} 的使用介绍
相较于 C++98,C++11扩大了 {} 的使用范围,使其可用于 所有 的内置类型和用户自定义的类型。
使用花括号初始化时,可添加 =,也可不添加。
1. 基本使用举例🌰:
/*struct Point{int _x; int _y;};*/
//整形常量
int x1 = 1;
int x2 = { 2 };
int x3{ 3 }; // (可以省略赋值符号)
// 数组
int array1[]{ 1, 2, 3, 4, 5 };
int array2[5]{ 1 };
// 结构体
Point p{ 1, 2 };
// new 表达式
int* pa = new int[4]{ 0 };
思考这个是啥?
int x4(1); // 这个是调用了 int 的构造函数
监视窗口查看上述变量如图:
2. 带参构造的自定义类型,对{}的使用举例🌰:
/*class Date
{
public:
*/explicit /*Date(int year, int month, int day)
:_year(year)
, _month(month)
, _day(day)
{
cout << "Date(int year, int month, int day)" << endl;
}
private:
int _year;
int _month;
int _day;
};*/
int main()
{
Date d1(2022, 1, 1); // old style:调用构造函数
Date d2 = { 2022, 1, 2 }; // 语法会识别:构造 + 拷贝构造 -- 在经过优化--> 直接构造
Date d3 { 2022, 1, 3 }; // 语法会识别:和d1一样,直接构造
return 0;
}
注:explicit 关键字:表示不允许 d2 初始化写法的发生,实际没什么太大的价值
2.std::initailizer_list
C++11 支持如下写法:
vector<int> v1 = { 1,2,3,4,5 };
vector<int> v2 = { 100,200,300 };
vector<int> v3 = { 1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9 };
vector 后面的 {},为什么个数没有匹配也能通过?
实际上,是因为 C++11 给不少容器增加了一个参数为 initializer_list 的初始化构造函数。
也就是说,这里的 vector 是由 {} 内的元素构造的 initailizer_list<int> 构造成的。


测试一下:
int main()
{
auto il = { 10, 20, 30 };
cout << typeid(il).name() << endl;
return 0;
}
------------------------------------------------------
输出结果:
class std::initializer_list<int>
🌰举例:让模拟实现的 vecto 也支持 {} 初始化和赋值,需要加上如下构造函数:
vector(initializer_list<T> il)
{
/*initializer_list<T>::iterator it = il.begin();
while (it != il.end())
{
push_back(*it);++it;
}*/
for (auto& e : il)
{
push_back(e); ++it;
}
}
模拟实现这个 vector,如果不添加带 std::initializer_list 参数类型的构造函数,会报错:“初始化”无法从 “initializer_list” 转化为 “vecter<int>”。
std::initializer_list 的应用场景
- 一般是作为 构造函数 的参数,目的是方便初始化容器对象。
- 也可以作为 operator= 的参数,这样就可以用大括号赋值。
重点使用事项 & 案例
- C++11 可以把任意常量给 initializer_list 的对象,也可以用 auto 自动生成。
- initializer_list 的数据存在常量区。
// initializer_list 类型的使用
// ps:为保持使用习惯,= 还是不省略了...
auto i1 = { 1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9 };
initializer_list<int>::iterator it1 = i1.begin();
auto i2 = { 100,200,300 };
initializer_list<int>::iterator it2 = i2.begin();
auto i3 = { 100,200,300 };
initializer_list<int>::iterator it3 = i3.begin();
cout << it2 << endl;
cout << it3 << endl; // 输出地址和 it2 一样!!!
// *it1 = 1; // 不能修改,因为是存在常量区的
- 使用支持 { } 构造的 也支持嵌套使用 { }
// Date 类 演示
/*Date d1(2023,5,20);
Date d2(2023,5,21);*/
// 写法1:识别到了里面的类型 initializer_list<Date>,然后构造的 vector
vector<Date> vd1 = {d1, d2};
// 写法2:匿名对象
vector<Date> vd2 = { Date(2023,5,20), Date(2023,5,21) };
// 写法3:C++ 两层嵌套
vector<Date> vd3 = { {2023,5,20}, {2023,5,20} };
- map 也支持这样的写法(因为 pair() 实现了 { } 的构造方式)
// map的初始化
map<string, string> dict = { {"one", "一"},{"two", "二"},{"three", "三"} };
pair<string, string> kv1 = { "four", "四" };
pair<string, string> kv2 { "five", "五" };
🥰如果本文对你有些帮助,请给个赞或收藏,你的支持是对作者大大莫大的鼓励!!(✿◡‿◡) 欢迎评论留言~~
本文主要介绍了C++中列表初始化的相关内容。C++98中{}可对数组或结构体元素初始化,C++11扩大了其使用范围,可用于所有内置和自定义类型。还介绍了std::initializer_list,其常作为构造函数或operator=的参数,方便容器对象的初始化和赋值。

被折叠的 条评论
为什么被折叠?



