可变参模板

  • ​​简介​​
  • ​​递归模板函数​​

简介

可变参模板是c++11引入的特别重要的一个特性,和 c 语言中的可变参一样,也是使用 ... 来表示的,如下:

template <typename ... Args>
void print(Args ...args)
{

}

上面的模板函数print可以接收任何类型、任何个数的对象作为实参,例如:

print<int,double,std::string,std::tuple>(10,18.8,"change",std::make_tuple<int,std::string,double>(88,"desk",19.9));

既然是任意形式,所以个数为 0 的模板参数也是可以的,如果不希望产生的模板参数个数为0,可以手动的定义至少一个模板参数:

template <typename T,typename ...Args>
void print(T t,Args ...args)
{

}

那么,具体该如何实现一个可变参的print呢?我们要做的第一个事情就是将 args 参数解包成具体的类型参数,比如将 args 解包成 int,double,std::string 类型的对象。对参数进行解包,到目前为止还没有一种简单的方法能够处理参数包,但有两种经典的处理手法:

  • 递归模板函数:先处理第一个参数,然后递归调用模板函数,并且提供一个终止模板函数
  • 变参模板展开:在c++17中引入

递归模板函数

递归是非常容易想到的一种手段,也是最经典的处理方法。这种方法不断递归地向函数传递模板参数,进而达到递归遍历所有模板参数的目的:

#include<iostream>
template<typename T0>
void printf1(T0 value)
{
std::cout << value << std::endl;
}

template<typename T,typename...Ts>
void printf1(T value,Ts... args)
{
std::cout << value << std::endl;
printf1(args...);
}

int main()
{
printf1(1,2,"123",1.1);
return 0;
}

这里你需要提供一个终止模板函数,以便在解包的过程中知道什么时候可以结束。