C++ 一致性初始化、初值列:initializer_list (c11)

本文详细介绍了C++11引入的列表初始化(一致性初始化)特性,包括局部变量的默认初始化、禁止窄化转换以及std::initializer_list的使用。通过示例展示了如何使用大括号进行初始化,并解释了为何大括号初始化不允许精度损失。同时,文章讨论了explicit关键字在抑制构造函数转换行为中的作用。

一 列表初始化/一致性初始化

在C++11之前,如何初始化一个变量或对象的概念比较混淆。初始化的场景可以发生在:小括号、大括号或赋值操作符中
C++11引入了“列表初始化/一致性初始化”,意思为:面对任何初始化动作,你可以使用相同语法,就是使用大括号

比如下方

int a = 10;
int b = { 10 };
int c{ 10 };
int d(10);

局部基础数据类型的默认初始化
对于局部变量的定义,如果我们没有给出初始值,那么这个变量定义的值是不明确的未知的
如果我们使用{}对普通数据类型的变量进行定义,即使没有给出初始值,那么会根据数据类型进行默认初始化

int i;    //乱值
//cout << "i==0" << ((i == 0) ? "true" : "false") << endl;//未初始化,编不过
int j{};  //0
cout << "j==0" << ((j == 0) ? "\ttrue" : "\tfalse") << endl;

int *p;   //p指向未知地址
//cout << "p==nullptr" << ((p == nullptr) ? "true" : "false") << endl;//未初始化,编不过
int *q{}; //q为nullptr
cout << "q==nullptr" << ((q == nullptr) ? "\ttrue" : "\tfalse") << endl;

vs不初始化就编不过
在这里插入图片描述

禁止窄化
“窄化”意为:精度降低或造成数值变动
对于一般的赋值与初始化,允许窄化的发生
对于大括号的初始化,其不允许窄化的发生,如果有,那么编译将不通过。
主要的原因是为了防止数据在转换中的丢失

int x1(5.3);   //正确,允许double向int转变,但是x1为5
int x2 = 5.3;  //正确,同上
//int x3{ 5.3 }; //错误,不允许,因为造成了数据丢失

char c1{ 7 };     //正确,7也属于char
//char c2{ 99999 }; //错误,99999不属于char的范围,不允许转换

std::vector<int> v1{ 1,2,3,4,5 }; //正确
//std::vector<int> v2{ 1.2,8,1.5 }; //错误,其中含有double数据

在这里插入图片描述
编译将直接报错

二 std::initializer_list

class P {
public:
	P(int a, int b) {
		m_vec.push_back(a);
		m_vec.push_back(b);
	};

	P(std::initializer_list<int> lst) {
		for (auto it : lst)
		{
			m_vec.push_back(it);
		}
	};

	void show()
	{
		for (auto it : m_vec)
		{
			cout << it <<"\t";
		}
		cout << endl;
	}
private:
	std::vector<int> m_vec;
};

MYINT main()
{
	P p(77, 5);      //调用给P(int, int)
	//P p2(77, 5, 20); //错误,构造函数参数不匹配

	P p3{ 77,5 };       //调用P(std::initializer_list<int>)
	p3.show();
	P p4 = { 77,5 };    //调用P(std::initializer_list<int>)
	p4.show();
	P p5{ 77,5,10,15 }; //调用P(std::initializer_list<int>)
	p5.show();

	system("pause");
	return 0;
}

//备注,如果P没有提供P(std::initializer_list<int>),那么上面的p3、p4将
//调用P(int, int),p5初始化将错误

在这里插入图片描述
explicit将抑制类的构造函数转换行为

class P {
public:
	P(int, int) {};
	explicit P(int, int, int) {};
};

int main()
{
	P p(77, 5);      //正确,调用P(int, int)
	P p2(77, 5, 20); //正确,调用explicit P(int, int, int)
	P p4 = { 77,5 }; //正确,调用P(int, int)

	//错误,explicit关键字抑制initializer_list列表使用P(int, int, int)构造函数
	//P p5= { 77,5,10 };
	system("pause");
	return 0;
}

编译直接报错
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值