模板initializer_list(c++11
模板initializer_list(c++11)
模板模板initializer_list是c++新增的。您可以使用初始化列表语法将STL容器初始化为一系列值:
vector<doulbe>payments{45.99,39.23,19.95,89.01};
创建一个4个元素的容器,并使用列表中的4个值来初始化这些元素。之所以可行,因为容器类实现在包含将模板initializer_list<T>
作为构造函数。例如,vector包含一个将模板initializer_list作为参数的构造函数,因此上面的声明和下面等价:
vector<double>payments({45.99,39.23,19.95,89.01};
这里显示地将列表指定为构造函数参数:
通常,考虑到c++11新增的通用初始化语法,可使用表示法{}而不是()来调用类构造函数:
shared_ptr<double>pd {new doulbe};
但如果使用类也有接受initializer_list
作为参数的构造函数,将有问题:
vector<int> vi{10};//?
这将表示使用哪个构造函数:
vector<int> vi(10);//10:未初始化的元素
vector<int> vi({10});//1个元素设置为10
如果有接受initializer_list作为参数的构造函数,则使用语法{}将调用该构造函数。因此在这个例子中,对应第二个。
所有initializer_list元素的类型都必须相同,但编译器将进行必要的转换:
vector<double> payments{45.99,39.23,19,89};
等同于:
vector<double>payments{45.99,39.23,19.0,89.0};
由于vector的元素类型为double,因此列表的类型为initializer_list<double>
,所以19和89被转换为double。
但不能进行隐式地窄化转换:
vector<int> values={10,8,5.5};//变窄,编译时间报错
不能隐式地将5.5转换为int。
除非类要用于处理长度不同的列表,否则让它提供接受initializer_list作为参数的构造函数没有意义。例如:对于存储固定数目的类,不能提供接受initializer_list作为参数的构造函数。下面的声明中,类包含三个数据成员,因此没有提供initializer_list作为参数的构造函数:
class Position
{
private:
int x;
int y;
int z;
public:
Position(int xx=0,int yy=0,int zz=0):x(xx),y(yy),z(zz){}
没有提供initializer_list
...
}
这样,使用语法{}时将调用构造函数Position(int,int,int):Position A={20,-3};//使用Position(20,-3,0)
使用initializer_list
使用initializer_list对象,必须包含头文件initializer_list。这个模板类包含成员函数begin()和end(),可以使用访问列表元素,还包含成员函数size(),该函数返回元素数.
例:
#include<iostream>
#include<initializer_list>
using namespace std;
double sum(initializer_list<double> il);
double average(const initializer_list<double> &ril);
int main()
{
cout<<"List 1: sum="<<sum({2,3,4})
<<",ave="<<average({2,3,4})<<'\n';
initializer_list<double> d1={1.1,2.2,3.3,4.4,5.5};
cout<<"List 2:sum="<<sum(d1)
<<",ave="<<average(d1)<<'\n';
d1={16.0,25.0,36.0,40.0,64.0};//赋给另一个
cout<<"List 3: sum="<<sum(d1)
<<",ave="<<average(d1)<<'\n';
return 0;
}
double sum(initializer_list<double> il)//安值传递
{
double tot=0;
for(auto p=il.begin();p!=il.end();p++)
tot+=*p;
return tot;
}
double average(const initializer_list<double> &ril)//引用传递;迭代器为const,不能修改值
{
double tot=0;
int n=ril.size();
double ave=0.0;
if(n>0)
{
for(auto p=ril.begin();p!=ril.end();p++)
tot+=*p;
ave=tot/n;
}
return ave;
}
注释:函数参数可以是字面量:{2,3,4};也可以是变量:d1。