zoukankan      html  css  js  c++  java
  • 003 可变参数模板

    可变参数模板

    一、可变参数模板

    template <typename T, typename ... Args> 
    void fun(T t, Args ... args);//合法 
    
    template <typename ... Args, typename T> 
    void fun(Args ... args, T t);//非法
     1 // Args是一个模板参数包; rest是一个函数参数包
     2 // Args表示零个或多个模板类型参数
     3 // rest表示林个或多个函数参数
     4 template <typename T, typename ... Args>
     5 void foo(const T &t, const Args& ... rest)
     6 
     7 int i = 0double  d = 3.14; strng s = "how now brown cow";
     8 foo(i, s, 42, d);
     9 foo(s, 42, "hi");
    10 foo(d, 42);
    11 foo("hi");
    12 
    13 void foo(const int&, const string&, const int&, const double&);
    14 void(const string&, const int&, const char[3]&);
    15 void foo(const double&, const string&);
    16 void foo(const char[3]&);

    二、sizeof...运算符

    【注意】当我们需要知道包中有多少个元素时,可以用sizeof...

     1 #include<iostream>
     2 #include<string>
     3 using namespace std;
     4 
     5 template <typename T, typename ... Args>
     6 void foo(const T&, const Args& ... rest)
     7 {
     8     cout << sizeof...(Args) << " ";  //模板类型参数的数目
     9     cout << sizeof...(rest) << endl; // 函数参数的数目
    10 }
    11 
    12 int main()
    13 {
    14     int i = 0; double  d = 3.14; string s = "how now brown cow";
    15     foo(i, s, 42, d);
    16     foo(s, 42, "hi");
    17     foo(d, 42);
    18     foo("hi");
    19 
    20     return 0;
    21 }

    运行结果:

    三、编译可变参数函数模板

    非可变参数模板比可变参数模板更特例化,因此编译器选择非可变参数版本。

     1 #include<iostream>
     2 #include<string>
     3 using namespace std;
     4 
     5 template <typename T>
     6 ostream& print(ostream &os, const T &t)
     7 {
     8     return os << t << endl;
     9 }
    10 
    11 template <typename T, typename ... Args>
    12 ostream &print(ostream &os, const T &t, const Args& ... rest)
    13 {
    14     os << t << " , ";
    15     return print(os, rest ...);
    16 }
    17 
    18 int main()
    19 {
    20     int i = 0;
    21     string s = "hello";
    22     
    23     print(cout, i);
    24     print(cout, i, s);
    25     print(cout, i, s, 42.1, 'A', "End");
    26     return 0;
    27 }

    运行结果:

    练习16.55

     

    四、包扩展

     1 #include <iostream>
     2 using namespace std;
     3 
     4 template <typename T>
     5 T accum(const T &t)
     6 {
     7     return t;
     8 }
     9 
    10 template <typename T, typename... Args>
    11 T accum(const T &t, Args... args)
    12 {
    13     return t + accum(args...);
    14 }
    15 
    16 int h()
    17 {
    18     return 42;
    19 }
    20 
    21 template <typename ...Args>
    22 int h(int t, Args ... args)
    23 {
    24     return t + h(args...);
    25 }
    26 
    27 void f(int i, int j = 0, int k = 0, int l = 0)
    28 {
    29     cout << i << " + "
    30         << j << " + "
    31         << k << " + "
    32         << l << " =  "
    33         << i + j + k + l << endl;
    34 }
    35 
    36 template<typename ... Args>
    37 void g(Args ... args)
    38 {
    39     cout << sizeof...(Args) << endl;
    40     cout << sizeof...(args) << endl;
    41     // h(a1, a2, a3, ..., an)
    42     f(args...);  
    43     // h(a1, a2, a3, ..., an)
    44     cout << h(args...) << endl; 
    45     //f(h(a1), h(a2), h(a3), ..., h(an))
    46     f(h(args) ...);  
    47     // f(h(a1, a2, a3, ..., an2)
    48     f(h(args ...));  
    49     // f(h(5,6,7,8) + a1, h(5,6,7,8) + a2, h(5,6,7,8) + a3, ..., h(5,6,7,8) + an)  
    50     f(h(5, 6, 7, 8) + args ...);                             
    51 }
    52 
    53 int main()
    54 {
    55     cout << accum(1, 2, 3, 4) << endl;
    56     g(1, 2, 3, 4);
    57     return 0;
    58 }

    运行结果:

    五、转发参数包

     模板特例化

    1. 全特化就是全部特化,即针对所有的模板参数进行特化。

    2. 偏特化就是部分特化,即针对部分模板参数进行特化。

    全特化和偏特化的定义不是很严格,所以有的时候不容易让人理解。

      1 #include <iostream>
      2 using namespace std;
      3 
      4 namespace templateTest {
      5 
      6     //模版泛化
      7     template<typename T>
      8     class iterator_traits
      9     {
     10     public:
     11         iterator_traits()
     12         {
     13             cout << "模版泛化" << endl;
     14         }
     15 
     16         ~iterator_traits()
     17         {
     18 
     19         }
     20     };
     21 
     22     //偏特化
     23     template<typename T>
     24     class iterator_traits<T*>
     25     {
     26     public:
     27         iterator_traits()
     28         {
     29             cout << "模版偏特化,特化常规指针" << endl;
     30         }
     31 
     32         ~iterator_traits()
     33         {
     34 
     35         }
     36     };
     37 
     38     //偏特化
     39     template<typename T>
     40     class iterator_traits<const T*>
     41     {
     42     public:
     43         iterator_traits()
     44         {
     45             cout << "模版偏特化,特化const指针" << endl;
     46         }
     47 
     48         ~iterator_traits()
     49         {
     50 
     51         }
     52     };
     53 
     54     //全特化
     55     template<>
     56     class iterator_traits<int>
     57     {
     58     public:
     59         iterator_traits()
     60         {
     61             cout << "模版全特化int类型" << endl;
     62         }
     63 
     64         ~iterator_traits()
     65         {
     66 
     67         }
     68     };
     69 };
     70 
     71 //泛化
     72 template<class U, class T>
     73 class Test
     74 {
     75 public:
     76     Test()
     77     {
     78         cout << "Test 泛化" << endl;
     79     }
     80 };
     81 
     82 //偏特化
     83 template< class T>
     84 class Test<int, T>
     85 {
     86 public:
     87 
     88     Test()
     89     {
     90         cout << "Test 偏特化" << endl;
     91     }
     92 };
     93 
     94 //全特化
     95 template<>
     96 class Test<int, char>
     97 {
     98 public:
     99 
    100     Test()
    101     {
    102         cout << "Test 全特化" << endl;
    103     }
    104 };
    105 template<typename T>
    106 void max(const T& t1, const T & t2)
    107 {
    108     cout << "模版函数泛化" << endl;
    109 
    110 }
    111 
    112 //其实函数模版不存在偏特化,只有全特化
    113 template<>
    114 void max<int>(const int& t1, const int& t2)
    115 {
    116     cout << "模版函数特化" << endl;
    117 }
    118 
    119 void main()
    120 {
    121     templateTest::iterator_traits<int> t1;
    122     templateTest::iterator_traits<float> t2;
    123     templateTest::iterator_traits<int *> t3;
    124     templateTest::iterator_traits<const int *> t4;
    125     Test<int, int> t5;
    126     Test<float, int> t6;
    127     Test<int, char> t7;
    128     max(5, 10);
    129     max(5.5, 10.5);
    130     system("pause");
    131 }

    运行结果:

  • 相关阅读:
    TCP和UDP知识总结
    使用 DataX 增量同步数据(转)
    python对象类型
    Asp.net mvc使用SignaIR
    数据库分库分表思路 [转]
    Linux基本操作 [转]
    RabbitMQ入门教程 [转]
    设计模式
    设计模式六大原则
    Javascript实现数组去重 [转]
  • 原文地址:https://www.cnblogs.com/sunbines/p/9087283.html
Copyright © 2011-2022 走看看