简介
- C++11增强了模板功能,在C++11之前,类模板和函数模板只能含有固定数量的模板参数,现在C++11中的新特性可变参数模板允许模板定义中包含0到任意个模板参数。
- 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号“…”。
- 参数包可以容纳0到N个模板参数,这几个参数类型可以为任意类型(可扩展参数)。f()没有传入参数,所以参数包为空,输出的size为0,后面两次调用分别传人两个和三个参数,故输出的size分别为2和3。
参数表
省略号的作用有两个:
- 省略号在模板参数左边,声明一个参数包,这个参数包可以包含0到任意个模板参数。
- 省略号在参数的右边,可以将参数包展开成一个个独立的参数。
可变参数函数模板
解析参数包
- 如果需要用参数包中的参数,则一定要将参数包展开。
有两种展开参数包的方法:
- 一种方法是通过递归的模板函数来将参数包展开
- 另外一种是通过逗号表达式和初始化列表方式展开参数包。
递归的模板函数方式展开参数包
#include<iostream>
template <typename T>
void Print(T t)
{
std::cout << t << std::endl;
}
template <typename T1, typename T2>
void Print(T1 t1, T2 t2)
{
std::cout << t1 << t2 << std::endl;
}
template <typename T1, typename T2, typename T3>
void Print(T1 t1, T2 t2, T3 t3)
{
std::cout << t1 << t2 << t3 << std::endl;
}
template<class T,class ...Args>
void Print(T head, Args... rest)
{
std::cout << "parameter" << head << std::endl;
Print(rest...);
}
int main(void)
{
Print(1, 2, 3, 4, 5);
system("pause");
return 0;
}
递归解析参数包结合tuple
#include<iostream>
#include<tuple>
using namespace std;
template<typename std::size_t I = 0, typename Tuple >
typename std::enable_if < I == std::tuple_size<Tuple>::value>::type printtp(Tuple t){}
template<typename std::size_t I=0,typename Tuple >
typename std::enable_if<I < std::tuple_size<Tuple>::value>::type printtp(Tuple t)
{
cout << get<I>(t)<<endl;
printtp<I + 1>(t);
}
template<typename ...Arg>
void print(Arg... arg)
{
printtp(std::make_tuple(arg...));
}
int main()
{
print(1, 2, "sqh", 4.5, true);
return 0;
}
初始化列表方式展开参数包
可变参数模板类
- 可变参数模板类是一个带可变模板参数的模板类
- 这个可变参数模板类可以携带任意类型任意个数的模板参数
std:.tuple就是一个可变模板类,它的定义如下:
template< class... Types >
class tuple;
|