一 列表初始化/一致性初始化
在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;
}
编译直接报错

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

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



