可变形参的函数
总共有三种方式:
- initializer_list (c++11)
- 省略符形参
- 可变参数模板 (c++11)
initializer_list
这种只适用于全部实参类型相同,我们可用initializer_list
类型的形参.
注意initializer_list
也是模板类型,但与vector
不同的是,initializer_list
中的元素值永远是常量值,我们无法去改变它的元素.
例子:
void error_msg(ErrorCode e, initializer_list<string> il)
{
cout<<e.msg()<<":";
for(const auto &elem:il)
cout<<elem<<" ";
cout<<endl;
}
省略号形参
这种方法是为了便于C++程序访问某些特殊C代码而设置的,这些C代码使用了varargs
的C标准库功能.
省略号形参应该仅仅用于C和C++通用的类型(基本类型),一般的类类型在传递给形参时都无法正确的拷贝.
典型例子: printf(const char* format,...);
声明:
省略号形参只能出现在最后的一个形参.
void func(param_list,...);
void func(...);
处理可变参数的标准宏:
//可变参数标准宏头文件
#include "stdarg.h"
//申明va_list数据类型变量pvar,该变量访问变长参数列表中的参数。
va_list pvar;
//宏va_start初始化变长参数列表。pvar是va_list型变量,记载列表中的参数信息。
//parmN是省略号"..."前的一个参数名,va_start根据此参数,判断参数列表的起始位置。
va_start(pvar, parmN);
//获取变长参数列表中参数的值。pvar是va_list型变量,type为参数值的类型,也是宏va_arg返回数值的类型。
//宏va_arg执行完毕后自动更改对象pvar,将其指向下一个参数。
va_arg(pvar, type);
//关闭本次对变长参数列表的访问。
va_end(pvar);
例子:
#include <stdarg.h>
function (parmN, ...)
{
va_list pvar;
va_start (pvar, parmN);
while(...)
{
...
f = va_arg (pvar, type);
...
}
va_end (pvar);
}
补充:
注意…形参入栈顺序,这和调用方式有关,请看我的另一篇博客.