形如printf这类的函数。
有时候我们无法确定参数的数量,这时我们需要可变参数个数的函数声明。
今天我们讲述两种方法来进行参数可变函数的声明
#include <iostream> #include <string> #include <initializer_list> #include<cstdarg> // 省略号参数的va_list等符号需要的头文件 using std::string; using std::cout; using std::endl; // C++11形式,使用参数列表的形式进行多参数传递 // 该方法限制是必须保证所有参数类型相同 void error_msg(std::initializer_list<string> il) { for(auto beg = il.begin(); beg != il.end(); ++beg) { cout << *beg << " "; } cout << endl; } // 该形式与printf的参数形式相同 // 但这种形式一般只用于C与C++的通用函数中 // 并且该形式的一种潜在风险是大多数类型的对象无法正确传递进来 int add(int pre, ...) { va_list arg_ptr; int sum=0; int nArgValue; sum+=pre; va_start(arg_ptr,pre); do { nArgValue=va_arg(arg_ptr,int); sum+=nArgValue; }while(nArgValue!=0); //自定义结束条件是输入参数为0 va_end(arg_ptr); return sum; } int main() { string expected("test error_msg 1"); string actual("test error_msg 2"); error_msg({"funcationX", actual, expected}); error_msg({"funcationX", "okay"}); cout << add(1,2,3,4,5,6,7,0) << endl; cout << add(1,2,3,4,0) << endl; }
编译运行结果如下:
在省略号的参数类型中,新加入的内容是几个宏的定义符号va_list 、va_start、va_end、va_arg
宏的定义如下:
/// \brief 返回arg_prt所指向的值,然后将它指向下一个元素 /// /// \param : [in][out] va_list arg_ptr 参数列表 /// \param : [in] type 指定参数被转换为的类型 /// \return : 当前参数的值 type va_arg( va_list arg_ptr, type ); /// \brief 将参数列表指针置为无效 /// /// \param : [in][out] va_list arg_ptr 参数列表 void va_end( va_list arg_ptr ); /// \brief 将arg_ptr 指向开头的参数 /// /// \param : [in][out] va_list arg_ptr 参数列表 /// \param : [in] prev_param 参数类型示范 void va_start( va_list arg_ptr, prev_param );