variadic Template(可变参数模板)

使用可变参数模板可以实现

  • 递归调用
  • 递归创建
  • 递归继承
  • 递归复合

variadic template

  • template
    • function template
    • class tempalate

变化的区别

  • 参数个数
    • 利用参数个数逐一递减的特性,实现递归函数调用,使用function template 完成
  • 参数类型
    • 利用参数个数逐一递减,导致参数函数类型也逐一递减实现递归集成,或递归复合,以class template 完成

sample

code

  • 例子1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void printX(){

    }
    // 这个是特化版本,当前版本存在时,下面的函数不会呗调用 既 void printX(const Types& args) 不会被调用
    template<typename T,typename... types>
    void printX(constT& firstArg,const Types& args){
    cout<<fistArg<<endl;
    print(args...);
    }

    template<typename T,typename... types>
    void printX(const Types& args){
    cout<<fistArg<<endl;
    print(args...);
    }
  • 例子2 重写printf function

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void printf(const char *s){
    while(*s){
    if(*s == '%'&&*(++s) !+'%'){
    throw std::runtime_error("invalid format string:missing argument")
    std::cout<<*s++;
    }
    }
    }

    template<typename T,typename... Args>
    void printf(const char*s,T value,Args... args){
    while(*s){
    if(*s == '%' && *(++s) !='%'){
    std::cout<<value;
    printf(++s,args...);
    return
    }
    std::cout<<*s++;
    }
    throw std::logic_error("extra argument provided to printf")
    }
  • 例子3 max函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    //stl_algo.h
    template<typename _ForwardIterator,typename _Compare>
    _ForwardIterator
    __max_element(_ForwardIterator __first,_ForwarIterator __last,_Compare __comp){
    if(__first==__last) return __first;
    _ForwardIterator __result=__first;
    while(++__first!=__last)
    if(__comp(result,__first))
    __result =__first;
    return __result;
    }

    template<typename _ForwardIterator>
    inline _ForwardIterator
    max_element(_ForwardIterator __first,_ForwarIterator __last){
    return __max_element(__first,__last,__iter_less_iter());
    }

    //stl_algo.h
    template<typename __Tp>
    inline Tp
    max(initializer_list<__Tp> __l){
    return *max_element(_l.begin(),_l.end());
    }

    //predefined_oops.h
    inline _Iter_less_iter
    __iter_less_iter(){
    return _Iter_less_iter();
    }
    //predefined_oops.h
    struct _Iter_less_iter{
    template<typename _Iterator1,
    typename _Iterator2>
    bool operator()(_Iterator1 __it1,_Iterator2 __it2)const{
    return *__it1<*__it2;
    }
    }

    cout<<max({1,2,3,4,5,6})<<endl;

    //改进

    cout<<max(1,2,3,4,5,6)<<endl;

    template<typename... Args>
    int maximum(int n,Args... args){
    return std::max(n,max(...args));
    }

例子4 类模板

用不同的方式处理first元素和last元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
cout<< make_tuple(7.5,string("hello"),bitset<16>(377),42);
//输出[7.5,hello,000000000101111001,42]

template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
os<<"[";
PRINT_TUPLE<0,sizeof...(Args),Args...>print(os,t);
os<<"]";
return os<<"]";
}

//boost: util/printtuple.hpp
//helper:print elment with index IDX of tuple
// with MAX element
template <int IDX,int MAX,typename... Args>
struct PRINT_TUPLE{
static void print(ostream& os,const tuple<Args...>& t){
os<<get<IDX>(t)<<(IDX+1==MAX?"":",");
PRINT_TUPLE<IDX+1,MAX,Args...>::print(os,t);
}
};

template<int MAX,typename... Args>
struct PRINT_TUPLE<MAX,MAX,Args...>{
static void print(std::ostream& os,const tuple<Args...>&t){}
};

例子5 用于递归继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
template<typename...,Values> class tuple;
template<>class tuple<>{};
template<typename Head,typenmae... Tail>
class tuple<Head,Tail...>:private tuple<Tail...>{
typedef tuple<Tail...> inherited;
public:
tuple(){}
tuple(Head v,Tail... vtail):m_head(v),inherited(vtail...){}
typename Head::type head(){return m_head;}
inherited& tail(){return *this;}
protected:
Head m_head;
};

//编译不过,改进版本

template<typename...,Values> class tuple;
template<>class tuple<>{};
template<typename Head,typenmae... Tail>
class tuple<Head,Tail...>:private tuple<Tail...>{
typedef tuple<Tail...> inherited;
protected:
Head m_head;
public:
tuple(){}
tuple(Head v,Tail... vtail):m_head(v),inherited(vtail...){}
//typename Head::type head(){return m_head;}
auto head()->decltype(m_head){return m_head;}
inherited& tail(){return *this;}
// protected:
// Head m_head;
};
// 简化版本

template<typename...,Values> class tuple;
template<>class tuple<>{};
template<typename Head,typenmae... Tail>
class tuple<Head,Tail...>:private tuple<Tail...>{
typedef tuple<Tail...> inherited;
protected:
Head m_head;
public:
tuple(){}
tuple(Head v,Tail... vtail):m_head(v),inherited(vtail...){}//相当于调用父类的构造
//typename Head::type head(){return m_head;}
Head head(){return m_head;}
inherited& tail(){return *this;} //相当于向上转型
protected:
Head m_head;
};

例子6

用于递归复合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<typename... Values>class tup;
template<>class tup<>{};
template<typename Head,typename... Tail>
class tup<Head,Tail...>{
typedef tup<Tail...> composited;
protected:
composited m_tail;
Head m_head;
public:
tup(){}
tup(Head v,Tail... vtail):m_tail(vtail...),m_head(v){}

Head head(){return m_head;}
composited& tail(){return m_tail;}
}