【共读Primer】47.[6.2]参数传递--含有可变形参的函数 Page197

形如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 );

 

posted @ 2018-09-05 09:10  chattyku  阅读(113)  评论(0编辑  收藏  举报