含有可变形参的函数
为了编写能处理不同数量实参的函数,C++11新标准提供了两种主要的方法:
- 如果所有的实参类型相同,可以传递一个名为 initializer_list 的标准库类型。
- 如果实参的类型不同,我们可以编写可变参数模板。
initializer_list 形参
如果函数的实参数量未知但是全部实参的类型都相同,可以使用 initializer_list 类型的参数:
| initializer_list提供的操作 | |
| initializer_list<T> lst; | 默认初始化T类型元素的空列表 |
| initializer_list<T> lst{a,b,c...}; | lst的元素数量和初始值一样多,lst的元素是对应初始值的副本,列表中的元素是const |
|
lst2(lst) lst2=lst |
拷贝或赋值一个initializer_list对象不会拷贝列表中的元素,拷贝后,原始列表和副本共享元素 |
| lst.size() | 列表中的元素数量 |
| lst.begin() | 返回指向lst中首元素的指针 |
| lst.end() | 返回指向lst中尾元素下一位置的指针 |
initializer_list 是一种模板类型,定义initializer_list 对象时,必须说明列表中所含元素的类型:
initializer_list<string> ls;//initializer_list的元素类型是string initializer_list<int> li;//initializer_list的元素类型是int
initializer_list 对象中的元素永远是常量值,无法改变initializer_list 对象中元素的值。
使用如下的形式编写输出错误信息的函数,使其可以作用于可变数量的实参:
void error_msg(initializer_list<string> il) { for (auto beg = il.begin(); beg != il.end(); ++beg) cout << *beg << " "; cout << endl; }
begin() 成员提供一个指向列表首元素的指针,end()成员提供一个指向列表尾后元素的指针。
函数首先初始化beg令其表示首元素,然后依次遍历列表中的每个元素。
在循环体中,解引用beg以访问当前元素并输出它的值。
向 initializer_list 形参中传递一个值得序列,则必须把序列放在一对花括号内:
//expected和actual是string对象 if (expected != actual) error_msg({ "functionX",expected,actual }); else error_msg({ "functionX","okay" });
上面代码调用同一个函数 error_msg,两次调用传递的参数量不同:
- 第一次调用传入了三个值
- 第二次调用只传入了两个
含有 initializer_list 形参的函数也可以同时拥有其他形参,调试系统可以可能有个名为 ErrCode 的类用来表示不同类型的错误,改写程序使其包含一个 initializer_list 形参和一个 ErrCode 形参:
void error_msg(ErrCode e, initializer_list<string> il) { cout << e.msg() << ": "; for (const auto& elem : il) cout << elem << " "; cout << endl; }
因为 initializer_list 包含 begin 和 end 成员,所以可以使用范围 for 循环处理其中的元素,遍历传给 li 形参的列表值,每次迭代访问一个元素。
调用这个版本的 error_msg 函数,需要额外传递一个 ErrCode 实参:
if (expected != actual) error_msg(Error(42),{ "functionX",expected,actual }); else error_msg(Error(0) ,{ "functionX","okay" });
省略符形参
省略符形参应该仅仅用于C和C++通用的类型,大多数类类型的对象在传递给省略形参时都无法正确拷贝。
省略符形参只能出现在形参列表的最后一个位置,它的形式无外乎以下两种:
void foo(parm_list, ...); void foo(...);
- 第一种形式指定了 foo 函数的部分形参的类型,对应于形参的实参将会执行正常的类型检查。
- 省略符所对应的实参无需类型检查。
- 在第一种形式中,形参声明后面的逗号是可选的。

浙公网安备 33010602011771号