可变参数模板代码实践,发给大家共勉!
/**
* 可变模板参数
*
* 田志泽 Tian zhize
* tianzhize137@163.com
* 背景
* 1、c++11 之前只能是固定的模板参数
*
* 模板函数 可变模板参数展示
* 递归展开
* 1、常见的方式
* 2、需要有同名的终止函数
*
* 逗号+初始化列表展开
* 1、逗号列表,(exp,exp2) 会执行所有的表达是,但是最后等于exp2
* 2、可以initializer_list<int> {}
* 类 可变参数模板展示
* 模板特化展开
* 继承展开
*
* notice
* 1、继承时候最后定义成struct 不要是 class , 因为calss 有权限问题
*
* sizeof
* 使用sizeof...(args) 可以获取参数个数
*
*/
#include <iostream>
#include <typeinfo> // 使用typeid
#include <tuple> //tuple
#include <algorithm>
using namespace std;
/**
* 可变模板参数定义
* 1、模板参数,... 放到class后,类型之前,表示 U 有多个
* 2、在参数之前,表示 args 有多个
*/
template <class ... U>
void func(U... args) {
cout <<sizeof...(args) << endl;
}
/**
* 展开参数包
* 1、递归方式
* 2、逗号分割符
*/
void print() {
}
template<class T,class ...Args>
void print(T t, Args ...args) {
cout << t << endl;
print(args...);
}
/**
* 遍历tuple
*/
template<int I = 0, class Tuple>
typename enable_if<I == tuple_size<Tuple>::value>::type printTp() {
}
template<int I = 0, class Tuple>
typename enable_if<I < tuple_size<Tuple>::value>::type printTp() {
printTp<I+1>();
}
/**
* 逗号+初始化列表
*/
template<class U>
void print(U u) {
cout << u << endl;
}
template<class ...Args>
void func1(Args ...arg) {
int arr[] = {(print(arg),0)...}; //逗号+初始化列表
initializer_list<int> a{(print(arg),0)...}; //
//gcc 还不支持
//initializer_list<int> b{([&]{print(arg);}(),0)...}; //lambda
}
/**
* 可变模板类
* 1、特化展开
* 2、基础展开
*/
// 第一部分,前项声明,这是可变参数模板类
template <class ...Args>
class Sum {
};
// 第二部分,如何展开的部分
template <class First, class ...Rest>
class Sum<First, Rest ...> { //类上添加<> 表示特化
enum { value = Sum<First>::value + Sum<Rest...>::value};
};
// 第三部分,特化的终止类
template <class Last>
class Sum<Last> {
enum{ value = sizeof(Last)};
};
/**
* 继承方法展开 可变参数模板类
* 1、notice 继承时候最后定义成struct 不要是 class , 因为calss 有权限问题
*/
// 第一部分前置声明
template<int ...>
class IndexSeq{};
// 第二部分
template<int N, int ... Rest>
struct MakeIndex : MakeIndex<N - 1, N-1, Rest...> {
};
// 第三部分,终止类
template<int ...Indexes>
struct MakeIndex<0, Indexes...> { //在N 等于 0的时候终止
typedef IndexSeq<Indexes...> type;
};
void test_class_variable_template() {
using T = MakeIndex<3>::type;
cout << typeid(T).name() << endl;
}
// 使用 Index 和 tuple 打印模板参数
template<int ...Indexes, class ... Args>
void helper_tuple(IndexSeq<Indexes...> index,tuple<Args...> tup) {
print(get<Indexes>(tup)...);
}
template <class ...Args>
void printArgs(Args ... args) {
//sizeof...(args) 可以获取参数个数
helper_tuple(typename MakeIndex<sizeof...(Args)>::type(),make_tuple(args...));
}
int main() {
// func();
// func(1,2);
// func1(1,2);
printArgs(1,3,4,5);
system("pause");
}