类模板
1 #include<iostream> 2 #include<vector> 3 #include<memory> 4 using namespace std; 5 6 template <typename T> class BlobPtr; 7 template <typename T> class Blob; 8 template <typename T> bool operator==(const Blob<T>&, const Blob<T>&); 9 10 template<typename T> class Blob { 11 friend class BlboPtr; 12 friend bool operator==(const Blob<T>&, const Blob<T>&); 13 public: 14 typedef typename vector<T>::size_type size_type; 15 16 Blob(); 17 Blob(initializer_list<T> il); 18 19 size_type size() const { return data->size(); } 20 bool empty() const { return data->empty(); } 21 void push_back(const T&) { data->push(t); } 22 void push_back(T &&t) { data->push_back(std::move(t)); } 23 24 void pop_back(); 25 T& back(); 26 T& opearator[](size_type i); 27 28 private: 29 shared_ptr<vector<T>> data; 30 void check(size_t i, const string &msg) 31 }; 32 33 template <typename T> 34 Blob<T>::Blob(): data(make_shared<vector<T>>()) {} 35 36 template <typename T> 37 Blob<T>::Blob(initializer_list<T> il): data(make_shared<vector<T>>(il)) {} 38 39 temlate <typename T> 40 void Blob<T>::check(size_type i, const string &msg) const 41 { 42 if (i >= data->size()) 43 throw out_of_range(msg); 44 } 45 template <typename T> 46 void Blob<T>::pop_back() 47 { 48 check(0, "pop_back on empty Blob"); 49 data->pop_back(); 50 } 51 52 template <typename T> 53 T& Blob<T>::back() 54 { 55 check(0, "back om empty Blob"); 56 return data->back(); 57 } 58 59 template <typename T> 60 T& operator[](size_type i) 61 { 62 check(i,"subscript out of range"); 63 return (*data)[i]; 64 } 65 66 /*--------------------------BlobPtr----------------------------------------------*/ 67 68 template <typename T> BlobPtr { 69 public: 70 BlobPtr(): curr(0) {} 71 BlobPtr(Blob<T> &a, size_r sz = 0): wptr(a.data), curr(sz) {} 72 73 T& opearator*() const; 74 75 BlobPtr& operator++(); //后缀自增 76 BlobPtr& opearator--(); 77 BlobPtr& opearator++(int); //前缀自减 78 BlobPtr& opearator--(int); 79 80 private: 81 size_t curr; 82 weak_ptr<vector<T>> wptr; 83 shared_ptr<vector<T>> check(size_t, const string&) const 84 }; 85 86 template <typename T> 87 shared_ptr<vector<T>> BlobPtr<T>::check(size_t i, const string &msg) const 88 { 89 auto ret = wptr.lock(); 90 if (!ret) 91 throw runtime_error("unbind BlobPtr"); 92 if (i >= ret->size()) 93 thow out_of_range(msg); 94 } 95 96 template <typename T> 97 T& BlobPtr*() const 98 { 99 auto p = check(curr, "dereference past end"); 100 return (*p)[curr]; 101 } 102 103 template <typename T> 104 BlobPtr<T>& BlobPtr<T>::operator--() 105 { 106 --curr; 107 check(curr, "decrement past bengin of BlobPtr"); 108 return *this; 109 } 110 111 template <typename T> 112 BlobPtr<T>& BlobPtr<T>::opearator++() 113 { 114 check(curr, "unbound BlobPtr"); 115 ++curr; 116 return *this; 117 } 118 119 template <typename T> 120 BlobPtr<T>& BlobPtr<T>::operator++(int) //后缀 121 { 122 BlobPtr ret = *this; 123 ++*this; 124 return ret; 125 } 126 127 template <typename T> 128 BlobPtr<T>& BlobPtr<T>::operator--(int) 129 { 130 BlobPtr ret = *this; 131 --*this; 132 return ret; 133 }
1 template <typename T> class Pal; // 前置申明,在将模板的一个特例声明为友元关系时要用到 2 class C { // C是一个普通的非模板类 3 friend class Pal<C>; // 用C实例化的Pal是C的一个友元 4 5 template <typename T> friend class Pal2; // pal2的所有实例都是C的友元;这种情况无需前置申明 6 }; 7 8 template <typename T> class C2 { // C2本身是一个类模板 9 friend class Pal<T>; // C2的每个实例将相同实例化的Pal声明为友元 10 template <typename X> friend class Pal2; // Pal2的所有实例都是C2的每个实例的友元,不需要前置声明 11 friend class Pal3; // pal3是一个非模板类,它是C2所有实例的友元 12 // 不需要Pal3的前置声明 13 };
控制实例化
• 模板在使用时才会被实例化,相同的实例可能出现在对各对象文件中。
• 当多个独立编译的源文件使用了相同的模板,并提供了相同的参数。那么每个文件都会有该模板的一个实例,在大系统中,这会增加额外开销。
• 通过显示实例化,避免这种开销。
extern template class Blob<string> //声明 template int compare(const int&, const int&) //定义