1、類模板的聲明
template <typename T>
class Stack{
...
}
2、在類模板內部,T可以像其他任何類型一樣,用於聲明成員變量和成員函數。
template <typename T>
class Stack{
private:
std::vector<T> elemes; // 存儲元素的容器
public:
Stack(); // 構造函數
void Push(const T& e); // 壓入元素
void Pop(); // 彈出元素
T Top() const; // 返回棧頂元素
};
這個類的類型是Stack<T>,其中T是模板參數。
3、類模板具體例子
#include<iostream>
#include<vector>
#include<string>
using namespace std;
template<typename T>
class Stack{
private:
vector<T> vec;
public:
void push(T const& elem);
void pop();
T top() const;
bool empty() const{
return vec.empty();
}
};
template<typename T>
void Stack<T>::push(T const& elem){
vec.push_back(elem);
}
template<typename T>
void Stack<T>::pop(){
if (vec.empty()){
throw out_of_range("Stack<>::pop():empty stack");
}
vec.pop_back();
}
template<typename T>
T Stack<T>::top() const{
if (vec.empty()){
throw out_of_range("Stack<>::pop():empty stack");
}
return vec.back();
}
int main(){
try{
Stack<int> istk;
istk.push(7);
istk.push(8);
istk.push(9);
cout << istk.top() << endl;
istk.pop();
cout << istk.top() << endl;
Stack<string> sstk;
sstk.push("aaa");
sstk.push("bbb");
sstk.push("ccc");
cout << sstk.top() << endl;
sstk.pop();
cout << sstk.top() << endl;
}
catch (exception const& ex){
cerr << "Exception:" << ex.what() << endl;
return EXIT_FAILURE;
}
system("pause");
return 0;
}
對於類模板,成員函數只有被調用的時候才被實例化。如果類模板中含有靜態成員,那麼用來實例化的每種類型,都會實例化靜態成員。
4、類模板的特化
爲了特化一個類模板,要在起始處聲明一個template<>.接下來聲明用來特化模版的類型,這個類型被用作模版實參。
//類模板的特化
template<>
class Stack<string>{
private:
deque<string> deq;
public:
void push(string const& elem);
void pop();
string top() const;
bool empty() const{
return deq.empty();
}
};
void Stack<string>::push(string const& elem){
deq.push_back(elem);
}
void Stack<string>::pop(){
if (deq.empty()){
throw out_of_range("Stack<>::pop():empty stack");
}
deq.pop_back();
}
string Stack<string>::top() const{
if (deq.empty()){
throw out_of_range("Stack<>::pop():empty stack");
}
cout << "模板的特化:";
return deq.back();
}
5、局部特化
template<typename T1, typename T2>
class MyClass{
...
};
// 局部特化,兩個模板參數類型相同
template<typename T>
class MyClass<T, T>{
...
};
// 局部特化,第2個模板參數是int
template<typename T>
class MyClass<T, int>{
...
};
// 局部特化,兩個模板參數都是指針類型
template<typename T1, typename T2>
class MyClass<T1*, T2*>{
...
};
6、缺省模板實參
可以爲類模板的參數定義缺省值,這些值被稱爲缺省模板實參,還可以引用之前的模板參數。
下面例子中的vector<T>就是缺省模板實參:
#include<iostream>
#include<vector>
#include<string>
#include<deque>
using namespace std;
template<typename T,typename Container=vector<T>>
class Stack{
private:
Container container;
public:
void push(T const& elem);
void pop();
T top() const;
bool empty() const{
return container.empty();
}
};
template<typename T, typename Container>
void Stack<T,Container>::push(T const& elem){
container.push_back(elem);
}
template<typename T, typename Container>
void Stack<T, Container>::pop(){
if (container.empty()){
throw out_of_range("Stack<>::pop():empty stack");
}
container.pop_back();
}
template<typename T, typename Container>
T Stack<T, Container>::top() const{
if (container.empty()){
throw out_of_range("Stack<>::pop():empty stack");
}
return container.back();
}
int main(){
try{
Stack<int> istk;
istk.push(7);
istk.push(8);
istk.push(9);
cout << istk.top() << endl;
istk.pop();
cout << istk.top() << endl;
Stack<string,deque<string>> sstk;
sstk.push("aaa");
sstk.push("bbb");
sstk.push("ccc");
cout << sstk.top() << endl;
sstk.pop();
cout << sstk.top() << endl;
}
catch (exception const& ex){
cerr << "Exception:" << ex.what() << endl;
return EXIT_FAILURE;
}
system("pause");
return 0;
}