您的位置:首页 > 编程语言 > C语言/C++

c++11新特性initializer_list模板

2017-12-22 22:37 507 查看

一、initializer_list介绍

模板initializer_list是C++11新增的。可以使用初始化列表语法将STL容器初始化为一系列的值;

std::vector<double> payments =  {45.99, 39.23, 19.95, 89.01};  //this is we usually do in our program;
same as      std::vector<double> payments  {45.99, 39.23, 19.95, 89.01};    //operator = can be omitted


创建一个包含4个元素的容器,并使用列表中的4个值来初始化这些元素;之所以这样可行,是因为vector类现在包含将initializer_list<T>作为参数的构造函数。例如,vector<double>包含一个将initializer_list<double>作为参数的构造函数,因此,上面的声明与下面的代码等价:

std::vector<double> payments ({45.99, 39.23, 19.95, 89.01}); //这里显示的将列表指定为构造函数参数;

要在代码中使用initializer_list对象,必须包含头文件initializer_list。这个模板包含成员函数begin()和end(),可以使用这些函数来访问列表中的元素。它还包含成员函数size(),该函数返回元素数目。

initializer_listde 迭代器的类型为const,因此不能修改initializer_list中的值:

payment.begin() = 35.0;  //not allowed

但是可以将一个initializer_list对象整体赋值给另外一个initializer_list对象:

payment = { 34.1, 42.2, 43.4, 56.4 };   //allowed,但所有拷贝实质上都是以引用方式进行的。

需要说明的是:上面的赋值操作,是会调用相应的以initializer_list为参数的构造函数的,这是我自己写程序测试的结果,测试程序如下:

#include <iostream>
#include <vector>

class MyNumber
{
public:
MyNumber (){
std::vector<int> mvec = {1, 2};
mVec = mvec;
std::cout<<"进入构造函数1"<<std::endl;
}
MyNumber(const std::initializer_list <int> &v) {
for (auto itm : v) {
mVec.push_back(itm);
}
std::cout<<"进入构造函数2"<<std::endl;
}

void print() {
for (auto itm : mVec) {
std::cout << itm << " ";
}
std::cout<<std::endl;
}
private:
std::vector<int> mVec;
};

int main()
{   MyNumber n;
//n = { 1, 2, 3, 4 };//这句会调用构造函数2
n.print();
return 0;
}


运行上面的程序,输出如下:



如果去掉main函数中注释掉的语句打开,重新运行,结果如下:



我的理解就是 { 1, 2, 3, 4 }就是一个initializer_list,所以运行到这儿的时候就回去调用构造函数2;见[4] ,在[4]下面留了疑问评论,因为博主的代码有一语句编译不过去;

总之一句话:提供initializer_list类的初衷就是让使用者能够将一系列的值传递给构造函数或其他函数

二、initializer_list的一些操作 

(1)initializer_list< T > lst : 默认初始化,T类型元素的空列表; 

(2)initializer_list< T > lst{a,b,c} : lst的元素数量和初始值一样多,lst的元素是对应初始值的副本,列表中的元素为const 

(3)lst2(lst)或者lst2 = lst:拷贝或者赋值一个initializer_list对象,拷贝后,原始列表和副本共享元素; 

(4)lst.size():列表中的元素数量; 

(5)lst.begin():返回指向lst中首元素的指针; 

(6)lst.end():返回指向lst中尾元素下一位置的指针。
见C++ primer,第六版中文版;

参考:

[1] C++ Primer Plus 第六版中文版 P724

[2] std::initializer_list

[3] C++11 初始化列表(initializer_list)

[4] 需要可变参数的时候,为什么不用vector代替initializer_list?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: