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;
}