泛型编程
泛型编程是指程序员可以以一种独立于任何特定数据类型的数据操作方式编写算法。
模板
模板是泛型编程的基础,是创建具体泛型类或函数的蓝图和公式。
实现原理
模板机制是一种语法糖,通过编译器根据模板创建具有的函数和类实例,编译器处理如下:
编译模板本身时, 检查语法信息。 使用模板时,检查参数类型是否匹配,数目正确与否; 对模板实例化时,进行实参推断。 生成具体的函数或类实例。 调用具体的实例
* 模板定义
template <typename T>//先声明模板参数 T
typename T add(const T &num1, const T &num2)//定义模板函数,注意参数的类型
{
return num1 + num2;
}
* 模板使用
add(1, 3)
* 编译器对模板实例化
int add(const int &num1, const int &num2)
{
return num1 + num2;
}
特例
模板中也可以使用特定的数据类型,可以减少编译器类型推导和生成实例,以提高效率。
全特例化; 将所有参数类型定死,类似于普通函数,是模板的一个特例,例如:
templete <>//标识我们在特例化模板
double add(const double &d1, const double &d2)//参数类型具体化
{
return d1 + d2;
}
偏特例;特例化部分参数(个数特化)或者参数类型(范围特化)。
template <typename T>
typename T add(const T &num1, const int &num2)//特化一个参数 为int
{
return num1 + num2;
}
范围特化:将参数限定在某个范围内(指针、const …)
template <typename T>
typename T add(const int num1, const T &num2)//将一个参数特化为 const int
{
return num1 + num2;
}
template <typename T>
typename T add(const int* num1, const T &num2)//将一个参数特化为 const int* 指针
{
return num1 + num2;
}
注意:如果同时存在模板和特例化模板, 当我们使用模板(参数与特例化一致),编译器会优先选择特例化模板实例,以避免类型推断等工作。
使用
函数模板
template <typename type> ret-type func-name(parameter list)
{
// 函数的主体
}
定义:
template <typename T>
inline T const& Max (T const& a, T const& b)
{
return a < b ? b:a;
}
使用:
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
运行:
Max(i, j): 39
类模板
template <class type> class class-name {
.
.
.
}
定义类:
template <class T>
class Stack {
private:
vector<T> elems; // 元素
public:
void push(T const&); // 入栈
void pop(); // 出栈
T top() const; // 返回栈顶元素
bool empty() const{ // 如果为空则返回真。
return elems.empty();
}
};
定义类成员函数:
template <class T>
void Stack<T>::push (T const& elem)
{
// 追加传入元素的副本
elems.push_back(elem);
}
使用:
Stack<int> intStack; // int 类型的栈
intStack.push(7); // 操作 int 类型的栈
说明
模板中的type T是占位符,可以在类被实例化的时候进行指定。您可以使用一个逗号分隔的列表来定义多个泛型数据类型。