[c++] 可变入参在c++中的使用

本文探讨了C/C++中动态参数列表的两种实现方式,一是传统的使用...结合va_list的方法,二是C++11引入的initializer_list<T>。通过对比,介绍了各自的特点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

c/c++的默认调用协定是 “从右向左遍历参数列表的方式压栈” ,并且回收栈空间的动作由函数调用者完成,对应的前缀是 _cdecl ,那么我们便可以利用这一特性,在函数的参数列表中使用 ... 来表示此处有 n 个入参,具体数量由调用者决定。这便是传统的动态参数列表实现方式。

c++ 11提供了更加便捷的 initializer_list<T> 来完成上述任务。

 

传统的动态参数列表:

#include <stdio.h>
#include "stdarg.h"

void myfunc(int argnum,...)
{
    va_list args;              //va_list 可以理解为一个指针
    va_start(args,argnum);     //此宏需要知道最后一个传递给自己的参数是谁

    int i;
    for(i=0;i<argnum;i++){
        int j;
        j=va_arg(args,int);           //以int类型为模板,读取当前args所指位置的值
        printf("%d\n",j);
    }


    va_end(args);
}


int main(int argc,char ** argv)
{
   myfunc(5,1,2,3,4,5);
}

有几点需要注意:

1)myfunc的参数列表不能只是...,一定要有第一个参数,这样才能定位函数调用栈的范围;

2)... 中的数据类型需要和 va_arg 的第二个参数匹配,否则在解析是便会出错,比如 传入int,但是va_arg解析char,这样便会根据机器的大小端情况做一定的数据截取,同时剩下的数据也将错位;

3)printf函数的第一个参数是用的字符串,然后使用%进行限制,这样其实现里只需要找到%,然后读取后一个字符,再进行switch判断,根据switch判断的类型决定 va_arg 的第二个参数使用什么

 

使用 initializer_list<T> 的动态参数列表:

这种方法,要求可变参数的类型一致,initializer_list<T>和vector<T>类似,只不过initializer_list里的值只能是常量,不可在函数中修改,例:

  void func(initializer_list<int> il);        //在函数实现中,il的使用和vector一样
  func({1,2,3,4,5});

  ...


  void func(initializer_list<int> list)
  {
      foreach(auto ele:list)
      {
            ....
      }
  } 

注意:因为 initializer_list 是模板函数,因此其参数类型必须保持一致,这点是一个局限性,灵活性而言,传统动态参数列表更加灵活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值