[TOC] # 1.递归方式展开可变模板参数 - 展开函数; - 递归中止函数 ``` template<typename T> T sum(T t) { return t; } template<typename T,typename ...Args> T sum(T first, Args... args) { //std::cout << "param:" << first << std::endl; return first + sum<T>(args...); } ``` # 2.逗号表达式和初始化列表展开参数 - 逗号表达式d=(a=b,c),先计算a=b;然后计算d=c; - 初始化列表:a[] = {((a=b),c)} ,初始化数组a长度为一,a[0] = c; - 下面既初始化了a[sizeof...(args)] = {0},也调用了sizeof...(args)次print(args); ``` template<typename T> void print(T t) { std::cout << "arg:" << t << std::endl; return; } template<typename ...Args> void print(Args... args) { int a[] = { ((print(args)),0)... }; } ``` # 3.使用lamda表达式的方式展开 ``` template<typename F,typename ...Args> void expand(const F &f, Args... args) { initializer_list<int>{(f(std::forward<Args>(args)), 0)...}; std::cout << std::endl; } void testLamDaExpand() { expand([](auto i) {std::cout << "i:" << i << " "; },1,2,3,4); } ``` # 4.可变模版参数类 ``` std::tuple<int, double, string> tp1; void testTuple() { tp1 = std::make_tuple(1, 2., "simon"); std::cout << "tp:" << std::get<string>(tp1) << std::endl; std::cout << "tp:" << std::get<0>(tp1) << std::endl; } ``` # 5.可变参数模版消除重复代码 ## 5.1非可变参数版本 ``` template<typename T> T* Instance() { return new T(); } template<typename T,typename T0> T* Instance(T0 t0) { return new T(t0); } template<typename T, typename T0,typename T1> T* Instance(T0 t0,T1 t1) { return new T(t0,t1); } struct A { A() { std::cout << "a" << std::endl; } }; struct B { B(int a) { std::cout << "a:" << a<< std::endl; } }; struct C { C(int a,int b) { std::cout << "a:" << a<<" b:" << b<<std::endl; } }; void testInstance() { A* a = Instance<A>(); B* b = Instance<B>(1); C* c = Instance<C>(1, 2); _CRT_UNUSED(a); _CRT_UNUSED(b); _CRT_UNUSED(c); } ``` ## 5.2通过可变参数优化 ``` template<typename T,typename ...Args> T* Instance1(Args&&... args) { return new T(std::forward<Args>(args)...); } void testInstance1() { A* a = Instance1<A>(); B* b = Instance1<B>(1); C* c = Instance1<C>(1, 2); _CRT_UNUSED(a); _CRT_UNUSED(b); _CRT_UNUSED(c); } ``` # 6.可变参数模版实现泛化的`delegate`(比较类似于`std::bind()`和`std::function()`组合 ``` template<typename T,typename R,typename ...Args> class MyDelegate { public: MyDelegate(T *t, R(T::*f)(Args...)) :m_t(t), m_f(f) {} R operator()(Args... args) { return (m_t->*m_f)(std::forward<Args>(args)...); } private: T *m_t; R(T::*m_f)(Args...); }; template<typename T,typename R,typename ...Args> MyDelegate<T, R, Args...> createDelegate(T *t,R (T::*f)(Args...)) { return MyDelegate<T, R, Args...>(t, f); } class Clazz { public: Clazz() {}; void fun1(int i) { std::cout << "i:" << i << std::endl; } void fun2(int i,int j) { std::cout << "i:" << i << " j:" << j << std::endl; } }; void testDelegate() { Clazz z; auto f1 = createDelegate(&z, &(Clazz::fun1)); f1(2); auto f2 = createDelegate(&z, &(Clazz::fun2)); f2(2, 2); } ```