【C++11】 {} 列表初始化的使用

本文主要介绍了C++中列表初始化的相关内容。C++98中{}可对数组或结构体元素初始化,C++11扩大了其使用范围,可用于所有内置和自定义类型。还介绍了std::initializer_list,其常作为构造函数或operator=的参数,方便容器对象的初始化和赋值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

列表初始化:用 {} 可以初始化一切


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= 的参数,这样就可以用大括号赋值。

重点使用事项 & 案例

  1. C++11 可以把任意常量给 initializer_list 的对象,也可以用 auto 自动生成。
  2. 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;			// 不能修改,因为是存在常量区的
  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} };
  1. map 也支持这样的写法(因为 pair() 实现了 { } 的构造方式)
// map的初始化
	map<string, string> dict = { {"one", "一"},{"two", "二"},{"three", "三"} };
	pair<string, string> kv1 = { "four", "四" };
	pair<string, string> kv2 { "five", "五" };


🥰如果本文对你有些帮助,请给个赞或收藏,你的支持是对作者大大莫大的鼓励!!(✿◡‿◡) 欢迎评论留言~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值