c++11 学习笔记 -可变参数模板

可变参数模板代码实践,发给大家共勉!

/**
 * 可变模板参数
 *
 * 田志泽 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");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值