列表初始化
约 931 字大约 3 分钟
2025-06-21
前要:首先需要说明白的是,“列表初始化”和“构造函数内的初始化列表”是两个东西,请您区分开来理解。
1.列表初始化
1.1.列表初始化的改变
在 C++98 中允许使用花括号对数组或者结构体元素进行统一的初始值设定。
//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 扩大了用花括号列表初始化的使用范围,可以用于所有内置类型和用户自定义类型。并且在使用列表初始化时,可以添加等号,也可以不添加。
并且列表中既可以是常量,也可以是变量。
//C++11 的列表初始化
struct Data
{
int _x;
int _y;
};
int main()
{
//内置类型中的初始化列表
int x1 = 1;
int x2{ 2 };
//数组类型中的初始化列表
int array1[]{ 1, 2, 3, 4, 5 };
int array2[5]{ 0 };
//自定义类型中的列表初始化
Data p{ 1, 2 };
//new 表达式中的列表初始化
int* pa = new int[4] { 0 };
Data* pd = new Data[2]{ {1, 2}, {3, 4} };
return 0;
}1.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;
}
Date(Date& d)
: _year(d._year), _month(d._month), _day(d._day)
{
cout << "Date(Date& d)" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1{ 2023, 5, 6 }; //单纯调用“构造”
Date d2 = { 2012, 3, 10 }; //调用“构造+拷贝构造”(也有可能发生优化,该语句在 Data 的构造函数加上关键字 explicit 时非法)
return 0;
}那么使用列表初始化构造一个容器(比如:vector 和 list)是怎么做到的呢?实际上,花括号内的常量数组会被识别为一个新的类类型:initializer_list。
//initializer_list 类型的存在
#include <iostream>
#include <initializer_list>
int main()
{
auto il = { 1,2,3 };
std::cout << typeid(il).name() << '\n';
return 0;
}并且该对象的数据在常量区存储,无法使用迭代器修改内部的值。
1.3.列表初始化的限制
由于列表初始化经常用于复杂的数据类型提供值列表,因此对类型转化的要求更加严格(具体表现为:初始化列表不允许“缩窄”的情况,也就是“不允许使用变量来列表初始化时,有可能超出初始化目标的情况”)。
//列表初始化中的限制
int main()
{
const int n1 = 31325;
int n2 = 66;
//char c1{ 31325 }; //无法初始化:常量值太大,初始化目标存不下
char c2{ 66 }; //允许初始化:常量值补大,初始化目标存得下
//char c3{ n1 }; //无法初始化:n1 变量类型为 int 有可能超出初始化目标范围
//char c4{ n2 }; //无法初始化:n2 变量类型为 int 有可能超出初始化目标范围
char c5{ (char)31325 }; //允许初始化
char c6{ (char)n1 }; //允许初始化
return 0;
}2.STL 中的列表初始化接口
C++ 11 除了新增加了一些容器:array、forward_list、unordered_set、unordered_map,还增加了一些新方法,基本上所有的容器都支持使用列表初始化的构造函数,这使得容器可以更加方便设置初始值。
更新日志
2025/11/24 07:31
查看所有更新日志