C++ 列表初始化
C++ 列表初始化
C++11 中,引入了用 {}
执行初始化的统一形式,C++11 称这种形式为统一初始化(Uniform initialization)
使用这种形式,可以解决所谓的“C++最令人恼怒的解析问题”
最令人恼怒的解析问题
该问题源于函数风格的转型和函数声明之间的相似性,导致很多代码都会被看做是函数声明
考虑这段代码
ifstream dataFile("ints.dat");
list<int> data(istream_iterator<int>(dataFile), istream_iterator<int>());
原意是用一对流迭代器去初始化列表,但运行后你会发现,它什么都没有做
原因在于编译器会认为 data 是一个函数
- 第一个参数 dataFile 是
istream_iterator<int>
类型的对象 - 第二个参数是不接受参数,返回
istream_iterator<int>
对象的函数
因为在函数声明中
- 包裹形参名的圆括号会被无视
int f(double d);
和int f(double (d));
是等价的- 参数是 double 类型的 d
- 空的圆括号会被认为是这里有一个函数类型的参数
int g(double ());
- 参数是返回值为 double,参数为空的函数
class Widget
{
//假设Widget有默认构造器
};
Widget w();
在这个例子中,w 并不是 Widget 对象,而是返回值为 Widget 类型的函数
C++ 11 前的解决方案
将参数声明包裹到圆括号里是非法的,但将函数调用的参数包裹在圆括号里是合法的:
list<int> data((istream_iterator<int>(dataFile)), istream_iterator<int>());
一种可读性更好、更合理的方式:
ifstream dataFile("ints.dat");
istream_iterator<int> begin(dataFile);
istream_iterator<int> end;
list<int> data(begin, end);
列表初始化
用列表初始化来解决上面的问题
list<int> data{ istream_iterator<int>{dataFile}, istream_iterator<int>{} };
Obj(1.0)
和 Obj{1.0}
的一个区别是:前者允许调用 Obj(int)
,而列表初始化不允许存在精度损失的类型转换
列表初始化的限制
列表初始化主要的限制是,如果一个类既有使用初始化列表的构造函数,又有不使用初始化列表的构造函数,那编译器会千方百计地试图调用使用初始化列表的构造函数,导致各种意外
vector<int> v{3, -1};
for (auto i : v) {
cout << i << endl;
}
比如上面的代码,可能本意是构造一个 3 个元素,初始值都是 -1 的 vector,但编译器会去尝试调用列表初始化构造函数,构造一个 [3, -1]
vector 出来
对此,比较好的做法是:
- 如果一个类没有使用初始化列表的构造函数时,初始化该类对象可全部使用统一初始化语法
- 如果一个类有使用初始化列表的构造函数时,则只应用在初始化列表构造的情况
initializer_list
initializer_list
定义在同名头文件中
template< class T >
class initializer_list;
initializer_list
是一种轻量级的代理对象,用来访问 T 类型的对象数组
- 可以实现为一对指针,或指针加数组长度
- 当
initializer_list
对象被拷贝时,底层数组不会被拷贝 - 底层数组是
const T[N]
类型的临时数组- 每个元素都是从
{}
列表中拷贝来的 initializer_list
对象中的元素永远是常量值,无法被修改
- 每个元素都是从
- 有点像
string_view
或 asio 中的 buffer
在以下几种情况中, initializer_list
对象会被自动构造
- 用
{}
列表初始化对象,且该对象的构造函数接受initializer_list
参数- 标准库容器基本都会接受
initializer_list<value_type>
类型的参数 - 因此标准库容器基本都是可以使用列表初始化的
- 标准库容器基本都会接受
- 用
{}
列表作为赋值语句的右操作数/函数的参数,对应的赋值运算符/函数接受initializer_list
参数
本文来自博客园,作者:路过的摸鱼侠,转载请注明原文链接:https://www.cnblogs.com/ljx-null/p/15929243.html