• C++ template 学习笔记(第三,四章)


      在这一章中主要讲述了class template相关的一些基础知识。主要分为:

        1. class template的声明和定义

        2. class template的使用

        3. class template的特化

        4. class template的偏特化

        5. class template的预设模版参数

      关于这几个方面,根据书上的例子,写了如下代码,注释部分为说明和一些注意事项:

      1 #include <iostream>
      2 #include <vector>
      3 
      4 template <typename T, typename CONT = std::vector<T> >          //模板参数缺省处理,默认为vector容器
      5 class Stack                                                  //在非特化的主模版声明中,类名后面不能跟尖括号说明类型
      6 {
      7 private:
      8     CONT elems;                                              //储存元素所用容器,在此处我们使用了默认参数 vector 做为容器
      9     
     10 public:
     11     void push(T const&);                            //类模版中的一些成员函数
     12     void pop();
     13     T top() const;
     14     inline bool empty() const {
     15         return elems.empty();
     16     }    
     17 };
     18 
     19 template <typename T, typename CONT>                              //除了特化类模版的类模版的成员函数的定义,
     20                                                           //前面需要添加“template <typename T, typename CONT>”说明
     21 void Stack<T, CONT>::push (T const& elem)                         //对于函数定义处,需要使用类模版的类型名 “Stack<T, CONT>::” 来限定
     22 {
     23     elems.push_back(elem);                                      //末尾添加元素
     24 }
     25 
     26 template <typename T, typename CONT>
     27 void Stack<T, CONT>::pop()
     28 {
     29     if (elems.empty ()){
     30         std::cout << "Stack<T, CONT>::pop(): empty stack!" << std::endl;
     31         return;    
     32     }
     33     elems.pop_back();                                       //删除最后一个元素
     34 }
     35 
     36 template <typename T, typename CONT>
     37 T Stack<T, CONT>::top() const
     38 {
     39         
     40     if (elems.empty ()){
     41         std::cout << "Stack<T, CONT>::top(): empty stack!" << std::endl;
     42         return;
     43     }
     44     return elems.back ();                                    //返回最后一个元素的值
     45 }
     46 
     47 /*
     48  *类模版的偏特化
     49  *(在这里尤其需要注意,定义模版的歧义性问题)
     50  */
     51 template<typename CONT>                                    //类模版的偏特化,针对double类型的参数声明,将使用此模版 ,
     52 class Stack<double, CONT>                                  //因此只需接收一个容器类型即可
     53 {
     54 private:
     55     CONT elems;
     56 public:
     57     void push(double const&);                              //在此处直接使用 double 类型即可
     58     void pop();
     59     double top() const;
     60     inline bool empty() const {
     61         return elems.empty();
     62     }
     63     
     64     inline void print()
     65     {
     66         std::cout << "Stack<double, CONT>_ >> " << elems.back() << std::endl;
     67     }
     68 
     69     Stack<double, CONT> operator=(Stack<double, CONT> const& stack_to);    //运算符重载,在此重载过程中使用了push_front函数
     70                                                              //因此,在选用容器时,许选用支持此函数的容器
     71 };
     72 
     73 template<typename CONT>
     74 void Stack<double, CONT>::push(double const& elem)
     75 {
     76     elems.push_back(elem);
     77 }
     78 
     79 template<typename CONT>
     80 void Stack<double, CONT>::pop()
     81 {
     82     if (elems.empty()){
     83         std::cout << "Stack<double, CONT>::pop(): empty stack!" << std::endl;
     84         return;
     85     }
     86     elems.pop_back();
     87 }
     88 
     89 template<typename CONT>
     90 double Stack<double, CONT>::top() const
     91 {
     92     if (elems.empty()){
     93         std::cout << "Stack<double, CONT>::top(): empty stack!" << std::endl;
     94         return;
     95     }
     96     return elems.back();
     97 }
     98 
     99 template<typename CONT>
    100 Stack<double, CONT> Stack<double, CONT>::operator= (Stack<double, CONT> const& stack_to)
    101 {
    102     if ((void*)this == (void*) &stack_to)
    103         return *this;
    104 
    105     Stack<double, CONT> temp(stack_to);
    106     elems.clear();
    107     while (!temp.empty())
    108     {
    109         elems.push_front(temp.top());
    110         temp.pop();
    111     }
    112     return *this;
    113 }
    114 
    115 /*
    116 *模版的特化
    117 *由于此处对模版的所有参数进行了特化,
    118 *因此只需在声明前加 “template<>” 即可
    119 *类的声明后面紧跟成员函数声明,
    120 *成员函数前面需要使用类模版的类型名“Stack<std::string, std::vector<std::string> >"限定
    121 *函数前无需添加 ”template<>" 
    122 */
    123 template<>
    124 class Stack<std::string, std::vector<std::string> >                    //类模板的特化
    125 {
    126 private:
    127     typename std::vector<std::string> elems;
    128 public:
    129     void push(std::string const&);
    130     void pop();
    131     std::string top() const;
    132     inline bool empty() const{
    133         return elems.empty();
    134     }
    135     inline void print(){
    136         std::cout << "Stack<std::string, std::vector<std::string> > _>> " << top() << std::endl;
    137     }
    138 };
    139 
    140 void Stack<std::string, std::vector<std::string> >::push(std::string const& elem)    //成员函数前面需要使用类模版的类型名“Stack<std::string, std::vector<std::string> >"限定
    141                                                                     //函数前无需添加 ”template<>" 
    142 {
    143     elems.push_back(elem);
    144 }
    145 
    146 void Stack<std::string, std::vector<std::string> >::pop()
    147 {
    148     if (elems.empty()){
    149         std::cout << "Stack<std::string, std::vector<std::string> >::pop(): empty stack!" << std::endl;
    150         return;
    151     }
    152     elems.pop_back();
    153 }
    154 
    155 std::string Stack<std::string, std::vector<std::string> >::top() const
    156 {
    157     if (elems.empty()){
    158         std::cout << "Stack<std::string, std::vector<std::string> >::top(): empty stack!" << std::endl;
    159         return;
    160     }
    161     return elems.back();
    162 }


      对上述代码的使用和测试代码如下:

     1 #include "template_3.hpp"
     2 #include <deque>
     3 #include <stdexcept>
     4 #include <cstdlib>
     5 using namespace std;
     6 
     7 int main ()
     8 {
     9 
    10     Stack<int> Stack_int;                                    //使用默认容器vector
    11 
    12     Stack_int.push(1);
    13     Stack_int.push(2);
    14     Stack_int.push(3);
    15     cout << "vector >> " << Stack_int.top() << endl;
    16     Stack_int.pop();
    17     cout << "vector >> " << Stack_int.top() << endl;
    18 
    19 
    20     Stack<int, std::deque<int> > Stack_deque_int;            //使用容器deque
    21 
    22     Stack_deque_int.push(1);
    23     Stack_deque_int.push(2);
    24     Stack_deque_int.push(3);
    25     cout << "deque >> " << Stack_deque_int.top() << endl;
    26     Stack_deque_int.pop();
    27     cout << "deque >> " << Stack_deque_int.top() << endl;
    28 
    29     Stack<string, vector<string> > Stack_string;
    30     Stack_string.push("aaa");
    31     Stack_string.push("bbb");
    32     Stack_string.push("cccc");
    33     Stack_string.print();
    34     Stack_string.pop();
    35     Stack_string.print();
    36 
    37     Stack<double, deque<double> > Stack_double, Stack_temp;
    38     Stack_double.push(1.1111);
    39     Stack_double.push(2.2222);
    40     Stack_double.push(3.3333);
    41     Stack_temp = Stack_double;
    42     Stack_temp.print();
    43     Stack_temp.pop();
    44     Stack_temp.print();
    45     return 0;
    46 }

       

    以上代码,均在gcc 4.6版本 编译通过~

  • 相关阅读:
    Spring常见面试题
    Mybatis常见面试题
    SQLSERVER查询整个数据库中某个特定值所在的表和字段的方法
    四款常见数据库比较同步软件汇总
    SQL Server常用函数整理
    比较经典的SQL面试题
    sqlserver查询数据库中有多少个表
    数据库设计三大范式
    MS SQL SERVER导出表结构到Excel
    flask-vue 解决跨域问题
  • 原文地址:https://www.cnblogs.com/fanqs/p/template_3.html
Copyright © 2020-2023  润新知