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版本 编译通过~

posted @ 2012-09-03 14:13  愤怒的豆沙包  阅读(502)  评论(0编辑  收藏  举报