C++ 泛型编程之可变参数包

C++ 泛型编程之可变模板参数


·variadic templates 可以表示0到任意个数、任意类型的参数

1.可变模板参数的展开:

template<typename... Args>	//可以将参数包展开一个个独立的参数
void func(Args... args);	//声明一个参数包Args... args 这个参数包可以包括0到任意个模板参数

1.1求参数包中参数的个数:若f()中未传入参数,size输出为0:

template <class... T>
void f(T... args)
{    
    cout << sizeof...(args) << endl; //打印变参的个数
}

f();       			//0
f(1, 2);    		//2
f(1, 2.5, "");    	//3

2.1递归函数方式展开参数包:

通过递归函数展开参数包,需要提供一个参数包展开的函数和一个递归终止函数,由递归终止结束递归:

#include <iostream>
using namespace std;
//递归终止函数
void print()
{
   cout << "empty" << endl;
}
//展开函数
template <class T, class ...Args>	// class ...Args :允许接收(0~N)个模板类型“T”
void print(T head, Args... rest)	//Args ...rest (0~N) 允许每个模板类型"T"接收(0~N)	
{									//个参数
   cout << head << endl;
   print(rest...);					//注意参数包调用时 ...参数包应在后面,可以理解一个接一个传
}									//入参数


int main(void)
{
   print(1,2,3,4);
   return 0;
}
--------------------------------------------
    打印结果:
    1
    2
    3
    4
   empty

解释:递归终止函数就是特化模板函数中参数包展开到最后一个的下一个的时候,当递归展开参数包结束后,函数原型为 func(parms) {假设func(parms)是展开函数},会变成func() 无参的形式,我们所要给出的递归终止函数就是这个。函数原型的无参形式!


2.1.2逗号表达式展开参数包

先理解逗号表达式:

 d = {a = b , c};

这个表达式的顺序为:b赋值给a,然后c做返回值赋值给d 既 a = b, d =c

因此利用这个执行顺序,我们可以初始化一个数组:

template<typename T>
void print(T t){
    cout<<t<<endl;
}

template<class ...Args>
void expand(Args ...args){
    int arr[] = {(print(args),0)...};
}

int main(){
    expand(1,2,3,4);
    return 0;
}
-----------------------------
    输出:
    1
    2
    3
    4

根据逗号表达式,先运行print(args),参数递归展开,第一个参数进入print执行打印参数,print(first_parm)运行结束,然后就是执行 int arr[] = {0};因为是递归展开第一层,arr只填入一个元素0,至此一轮递归结束。开始继续递归,直到运行prin(4),arr[]又填入一个元素0后,递归结束。至此expand运行结束,依次打印输出1,2,3,4,此外,arr在参数包展开的过程中,被初始化为int arr[ sizeof....(args) ],大小为4,元素都为0的数组。

posted @   雨和风  阅读(76)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示