C++ 函数传递多参数处理 可变参数模板

文章目录

    • 1、initializer_list形参
    • 2、省略符形参va_list
    • 3、可变参数模板

1、initializer_list形参

如果函数的实参数量未知但是全部实参的类型都相同,我们可以使用initializer_list类型的形参(C++11新标准)
initializer_list提供的一些操作:

#include // 头文件
initializer_list lst; // 默认初始化,T类型元素的空列表
initializer_list lst{a,b,c…}; // 初始化为初始值列表的副本
lst2(lst) // 拷贝或赋值不会拷贝列表中的元素;拷贝后,
lst2 = lst // 原始列表和副本共享元素
lst.size() // 列表中的元素数量
lst.begin() // 返回指向lst中首元素的指针
lst.end() // 返回指向lst中尾元素下一位置的指针

测试代码:

#include 
#include
using namespace std;

int addSum(initializer_list<int> li)
{
	int sum = 0;
	for (auto i = li.begin(); i != li.end(); ++i)
	{
		sum += *i;
	}
	return sum;
}

int main()
{
	int sum = addSum({ 1, 2, 3, 4, 5, 6 });		//需要加{}
	cout << sum << endl;
	return 0;
}

测试结果:
C++ 函数传递多参数处理 可变参数模板_第1张图片

2、省略符形参va_list

经典的打印函数printf就是用这种方法

int printf(const char* format, …)

用到的几个宏定义

#include // C中是 
  
// va_list是一种数据类型,args用于持有可变参数。 
// 定义typedef char* va_list; 
va_list args; 
  
// 调用va_start并传入两个参数:第一个参数为va_list类型的变量 
// 第二个参数为"..."前最后一个参数名 
// 将args初始化为指向第一个参数(可变参数列表) 
va_start(args, paramN); 
  
// 检索参数,va_arg的第一个参数是va_list变量,第二个参数指定返回值的类型 
// 每一次调用va_arg会获取当前的参数,并自动更新指向下一个可变参数。 
va_arg(args,type); 
  
// 释放va_list变量 
va_end(args);

测试代码:


#include 
#include
#include
using namespace std;

int addSum(int count,...)	//按从右到左的顺序将参数入栈,栈顶是count(表示参数个数)
{
	int sum = 0;
	va_list args;
	va_start(args, count);	//args指向栈顶
	for (int i = 0; i < count; ++i)
	{
		sum += va_arg(args, int);
	}
	return sum;
}

int main()
{
	int sum = addSum( 6,1, 2, 3, 4, 5, 6 );		//需要预先设定元素个数
	cout << sum << endl;
	return 0;
}

3、可变参数模板

典型用法

// Args是一个模板参数包;rest是一个函数参数包 
template <typename T, typename...Args> 
void foo(const T &t, const Args&...rest); 

可变参数函数模板通常是递归的。第一步调用处理包中的第一个实参,然后用剩余的实参调用自身。为了终止递归,我们还需要定义一个非可变参数的函数模板:

测试代码:

#include 
#include
#include
using namespace std;

//终止递归
template<typename T>
T addSum(T val)
{
	return val;
}

template<typename T,typename ... Args>
T addSum(T first,Args... args)	//
{
	return first+addSum<T>(args...);		//递归调用自身,直到没有参数,所以需要设置终止递归特化函数
	//1:1+addSum(2,3,4,5,6)
	//2:2+addSum(3,4,5,6)
	//3:3+addSum(4,5,6)
	//4:4+addSum(5,6)
	//5:5+addSum(6)	//最后一次调用上面的终止递归函数,return后依次递归返回值
}

int main()
{
	int sum = addSum(1, 2, 3, 4, 5, 6 );		//
	cout << sum << endl;
	return 0;
}



你可能感兴趣的:(C++,c++,数据结构)