模板可以包含类型参数(如 typename T) 和 非类型参数(如 int n)。模板还可以包含本身就是模板的参数,这种新增的特性,用于实现 STL 。
看下面的代码:
stacktp.h
[C++] 纯文本查看 复制代码 // stacktp.h -- a stack template
#ifndef STACKTP_H_
#define STACKTP_H_
template <class Type>
class Stack
{
private:
enum {MAX = 10}; // 常量
Type items[MAX]; // 栈
int top; // 栈顶
public:
Stack();
bool isempty();
bool isfull();
bool push(const Type & item); // 压栈
bool pop(Type & item); // 出栈
};
template <class Type>
Stack<Type>::Stack()
{
top = 0;
}
template <class Type>
bool Stack<Type>::isempty()
{
return top == 0;
}
template <class Type>
bool Stack<Type>::isfull()
{
return top == MAX;
}
template <class Type>
bool Stack<Type>::push(const Type & item)
{
if (top < MAX)
{
items[top++] = item;
return true;
}
else
return false;
}
template <class Type>
bool Stack<Type>::pop(Type & item)
{
if (top > 0)
{
item = items[--top];
return true;
}
else
return false;
}
#endif
temppram.cpp
[C++] 纯文本查看 复制代码 // tempparm.cpp – 模板作为参数
#include <iostream>
#include "stacktp.h"
template <template <typename T> class Thing>
class Crab
{
private:
Thing<int> s1;
Thing<double> s2;
public:
Crab() {};
// 假设 Thing 类有 push() 和 pop() 成员
bool push(int a, double x) { return s1.push(a) && s2.push(x); }
bool pop(int & a, double & x){ return s1.pop(a) && s2.pop(x); }
};
int main()
{
using std::cout;
using std::cin;
using std::endl;
Crab<Stack> nebula;
// Stack 必须匹配 template <typename T> class thing
int ni;
double nb;
cout << "Enter int double pairs, such as 4 3.5 (0 0 to end):\n";
while (cin>> ni >> nb && ni > 0 && nb > 0)
{
if (!nebula.push(ni, nb))
break;
}
while (nebula.pop(ni, nb))
cout << ni << ", " << nb << endl;
cout << "Done.\n";
return 0;
}
在 temppram.cpp 开头有下面的语句:- template <template <typename T> class Thing>
- class Crab
复制代码 template <typename T> class Thing 是模板参数,其中 template <typename T> class 是类型,Thing 是参数。
假设有如下声明:如果该声明要合法,那模板参数 King 就必须是一个模板类,并且其声明与模板参数 Thing 的声明匹配:
template <typename T>
class King { ... };
在 temppram.cpp 中还声明了两个对象:
Thing<int> s1;
Thing<double> s2;
那么对于上述的 legs 将用 King<int> 替换 Thing<int>,用 King<double> 替换 Thing<double> 。
然而,temppram.cpp 中包含了下面的声明:这样,Thing<int> 将被实例化为 Stack<int> ,而 Thing<double> 将被实例化为 Stack<double> 。总之,模板参数 Thing 将被替换为声明 Crab 对象时被用作模板参数的模板类型。
Crab 类的声明对 Thing 代表的模板类做了假设,即这个类包含一个 push() 方法,包含了一个 pop() 方法,且这些方法有特定的接口。Crab 类可以使用任何与 Thing 类型声明匹配,并包含方法 push() 和 pop() 的模板类。
还可以混合使用模板参数和常规参数。例如,Crab 类的声明还可以如下打头:- template <template <typename T> class Thing, typename U, typename V>
- class Crab
- {
- private:
- Thing<U> s1;
- Thing<V> s2;
- ...
- };
复制代码 现在,成员 s1 和 s2 可以存储的数据类型为泛型,而不是用硬编码指定的类型。对于上述的 nebula 声明,可以修改成如下这样:- Crab<Stack, int, double> nebula; // T=Stack, U=int, V=double
复制代码 模板参数 T 表示一种模板类型,而类型参数 U 和 V 表示非模板类型。
|