注意事项:
1.不能将模板成员函数放在独立的实现文件中,因为编译器在实例化模板时必须看到模板完全的确切的定义
而普通的函数和类是不需要编译器来实例化的,所以不需要看到定义,只要知道声明就可以了
Stack.h文件
--------------------------
template<typename T>
class Stack{
enum{MAX = 10};
T items[MAX];
int ntop;
public:
Stack();
bool isempty();
bool isfull();
bool push(const T &item);
bool pop(T &item);
}
template<typename T>
Stack<T>::Stack()
{
top = 0;
}
template<typename T>
bool Stack<T>::isempty()
{
return top == 0;
}
template<typename T>
bool Stack<T>::isfull()
{
return top == MAX;
}
template<typename T>
bool Stack<T>::push(const T &item)
{
if(isfull())
return false;
items[top++] = item;
return true;
}
template<typename T>
bool Stack<T>::pop(T &item)
{
if(isempty())
return false;
item = items[--top];
return true;
}
-----------------------------------
2.必须显示的提供参数类型
Stack<int> myintS; Stack<std::stirng> mystrS;
3.类外定义的成员函数必须使用模板声明
template<typename T>
Stack<T>::Stack()
{
top = 0
}
4. 使用模板类时一定要注意具体类型的实际情况,如数组 = 的操作 。。。,所以要具体情况具体分析
5. 模板的非类型参数或表达式参数只能是 整形、枚举、指针、引用,并且不能被取地址,不能被修改
ArrayTP<typename T,int n>
n就是非类型参数或者表达式参数,进入++n或&n等操作,模板实例化时必须是常量表达式
6.模板的具体化
6.1 隐式实例化 即编译器使用通用模板提供的处方生成实例
6.2 显示实例化 在模板类的名称控件中声明
template ArrayTP<std::string,10>;
template Stack<int>;
这样编译器编译时就会显示生成这两种类型的实例化,就无需等到创建对象时在实例化了
6.3 显示具体化 特定类型的操作可能不同,这时需要为特定类型显示具体化
显示具体的格式:
template<> class ArrayAP<const char *>
{
...
}
模板类还可以作为类的成员,模板还可以作为模板参数,模板类还可以有友元函数,约束性模板友元,非约束性模板友元等等......
还可以使用typedef 或using定义别名
typdef ArraryAP<int> AINT;
template<typename T>
using AINT = ArraryAP<int>;