nitializer\_list是C++11提供的新类型,定义在头文件中。
用于表示某种特定类型的值的数组,和vector一样,initializer\_list也是一种模板类型。
```
template< class T >
class initializer_list;
```
## 列表初始化
C++11扩大了初始化列表的适用范围,使其可用于所有内置类型和用户定义的类型。无论是初始化对象还是某些时候为对象赋新值,都可以使用这样一组由花括号括起来的初始值了。使用初始化列表时,可添加=,也可不添加。
```
//定义一个变量并初始化
int units_sold=0;
int units_sold(0);
int units_sold={0}; //列表初始化
int units_sold{0}; //列表初始化
```
当初始化列表用于内置类型的变量时,这种初始化形式有一个重要特点:如果我们使用列表初始化值存在丢失信息的风险,则编译器将报错:
~~~
long double ld=3.1415926536;
int a={ld},b={ld}; //错误:转换未执行,因为存在丢失信息的风险
int c(ld),d=ld; //正确:转换执行,且确实丢失了部分值
~~~
## initializer\_list的使用
它提供的操作如下:
~~~
initializer_list<T> lst;
//默认初始化;T类型元素的空列表
initializer_list<T> lst{a,b,c...};
//lst的元素数量和初始值一样多;lst的元素是对应初始值的副本
lst2(lst)
lst2=lst
//拷贝或赋值一个initializer_list对象不会拷贝列表中的元素;拷贝后,原始列表和副本元素共享
lst.size() //列表中的元素数量
lst.begin() //返回指向lst中首元素的指针
lst.end() //返回指向lst中尾元素下一位置的指针
~~~
需要注意的是,initializer\_list对象中的元素永远是常量值,我们无法改变initializer\_list对象中元素的值。并且,拷贝或赋值一个initializer\_list对象不会拷贝列表中的元素,其实只是引用而已,原始列表和副本共享元素。
和使用vector一样,我们也可以使用迭代器访问initializer\_list里的元素
~~~
void error_msg(initializer_list<string> il)
{
for(auto beg=il.begin();beg!=il.end();++beg)
cout<<*beg<<" ";
cout<<endl;
}
~~~
如果想向initializer\_list形参中传递一个值的序列,则必须把序列放在一对花括号内:
~~~
//expected和actual是string对象
if(expected != actual)
error_msg({"functionX",expectde,actual});
else
error_msg({"functionX","okay"});
~~~
说了这么多,那initializer\_list到底有什么应用呢?
有了initializer\_list之后,对于STL的container的初始化就方便多了,比如以前初始化一个vector需要这样:
~~~
std::vector v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
~~~
而现在c++11添加了initializer\_list后,我们可以这样初始化
~~~
std::vector v = { 1, 2, 3, 4 };
~~~
并且,C++11允许构造函数和其他函数把初始化列表当做参数。
~~~
#include <iostream>
#include <vector>
class MyNumber
{
public:
MyNumber(const std::initializer_list<int> &v) {
for (auto itm : v) {
mVec.push_back(itm);
}
}
void print() {
for (auto itm : mVec) {
std::cout << itm << " ";
}
}
private:
std::vector<int> mVec;
};
int main()
{
MyNumber m = { 1, 2, 3, 4 };
m.print(); // 1 2 3 4
return 0;
}
~~~
- C++基础
- 什么是 POD 数据类型?
- 面向对象三大特性五大原则
- 低耦合高内聚
- C++类型转换
- c++仿函数
- C++仿函数了解一下?
- C++对象内存模型
- C++11新特性
- 智能指针
- 动手实现C++的智能指针
- C++ 智能指针 shared_ptr 详解与示例
- 现代 C++:一文读懂智能指针
- Lamda
- c++11多线程
- std::thread
- std::async
- std::promise
- std::future
- C++11 的内存模型
- 初始化列表
- std::bind
- std::tuple
- auto自动类型推导
- 可变参数模板
- 右值引用与移动语义
- 完美转发
- 基于范围的for循环
- C++11之POD类型
- std::enable_if
- C++14/17
- C++20
- 协成
- 模块
- Ranges
- Boost
- boost::circular_buffer
- 使用Boost.Asio编写通信程序
- Boost.Asio C++ 网络编程
- 模板
- 模板特化/偏特化
- C++模板、类模板、函数模板详解都在这里了
- 泛化之美--C++11可变模版参数的妙用
- 模板元编程
- 这是我见过最好的模板元编程文章!