先引入传递参数的两种方式,即值传递和引用传递,我们在编写程序时因为无法预知向函数传入几个实参,从而函数形参也无法确定,所以c++新标准提供了两种主要的方法,即
1 如果实参类型相同,但数量未知,可以使用一个名为initialize_list的标准库类型。
2 如果实参类型不用,也许数量也未知,使用可变参数模板。
initialize_list的标准库类型
使用时添加同名的头文件即#include <initialize_list>,和vector一样,initialize_list也是一种模板类型,定义initialize_list对象也相同,即
initialize_list <T> lit; //默认初始化,T类型元素的空列表
initialize_list<T> lit {a,b,c}; //lit元素数量与初始值给的数量相同,列表中元素都是const类型,值无法改变
lit1 = lit2;
lit1(lit2); //两者相同
注意:如果向initialize_list形参中传递一个值得序列,则必须把序列放在一对花括号中。
例1:
int iCount(initialize_list<int> lst)
{
int count = 0;
for(auto val : lst)
count += val;
renturn count;
}
cout << "1,2,3,4,5,6的和是:" << iCount({1,2,3,4,5,6}) << endl;
可变参数模板
一个可变参数模板就是一个接受可变数目参数的模板函数或模板类,可变数目的参数为参数包,有两种参数包,即模板参数包表示零个或多个模板参数,函数参数包即表示零个或多个函数参数。
用一个省略号来指出一个模板参数或函数参数表示一个包,如:
template <typename T,typename … args> //args是一个模板参数包
void foo(const T &t,const args& … rest); //rest是一个函数参数包,foo函数参数列表包含一个const &类型的参数,指向T的类型,还包含一个rest函数参数包,此包表示零个或多个函数参数。
如:
int i = 0;double d = 3.14;string s = "some string";
foo(i,s,42,d); //包中有三个参数
foo(s,42,"hi"); //包中有两个参数
foo(d,s); //包中有一个参数
编译器会为foo实例化为
void foo(const int&,const string&,const int&,const double&);
void foo(const string&,const int&,const string&);
void foo(const double&,const string&);