一、template模板
(1)函数模板
template<typename T>
void Swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
- 上述代码是一个交换任意变量的函数模板, typename 是一个用来定义模板参数的关键字,也可以用关键字class(类模板常用)。
#include <iostream>
#include <string>
using namespace std;
template<typename T>
void Swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
int main()
{
int x = 10;
int y = 20;
Swap(x, y); // 隐式实例化,编译器自动推演
//Swap<int>(x, y); //显示实例化,编译器根据传入的类型直接生成对应类型的代码。
cout << x << " " << y << endl;
double i = 1.1;
double j = 2.2;
Swap(i, j);
//Swap<double>(i, j);
cout << i << " " << j << endl;
return 0;
}
- 在编译阶段, 编译器根据传入的实参类型来推演生成对应类型的函数(隐式实例化)。使用Swap函数模板生成了两份不同类型的Swap交换函数,调用时分别调用。
- 也可以显示调用**(显式实例化)**。Swap(x, y);
①模板参数的匹配原则:
// 专门处理int 的加法函数
int Add(int x, int y)
{
return x + y;
}
// 通用加法函数
template<class T>
T Add(T x, T y)
{
return x + y;
}
void Test()
{
Add(1, 2); // 与非模板函数匹配,编译器不需要特化
Add<int>(1, 2); // 与模板函数匹配,调用编译器特化的Add版本
}
- 有现成,吃现成
- 有现成,但不够匹配; 有模板就会选择模板,并实例化模板(编译器生成相应的代码,并调用该代码)。
(2)类模板
//template<class T1, class T2, ...> 可以有多个参数
template<class T>
class Stack
{
public:
void Push()
{
// ...
}
private:
T* _a;
int _size;
int _capacoty;
};
-
T 可以表示不同类型的栈,即在同一个文件中,可以根据类模板实例化出多个不同类型的数据的栈
-
int main() { Stack<int> st1; // 存储int 型数据的栈 Stack<double> st2; // 存储double 类型数据的栈 return 0; }
-
-
类模板的实例化必须显式实例化。
①类模板的实例化:
// Stack 是类的名字, Stack<int> 才是类型
Stack<int> st1;
Stack<double> st2;
- 类模板的名字不是真正的类,实例化的结果才是真正的类。
②模板的成员函数声明与定义分离:
// 类模板中函数放在类外定义时,需要加入参数模板。并且尽量在同一个文件中写。
template<class T>
Stack<T>::~Stack()
{
if (_a)
{
delete[] _a;
}
_size = _capacoty = 0;
}
- 类模板中函数放在类外定义时,需要加入参数模板。并且尽量在同一个文件中写。
二、STL标准模板库
- 全称standard template library 标准模板库
- 是C++标准库的重要组成部分, 标准库中包括STL标准模板库。
六大组件:
-
容器(string 字符串, vector 顺序表, list 链表等…);
-
迭代器(iterator, const_iterator, reverse_iterator…);
-
仿函数(greater, less…);
-
算法(find, swap, reverse, sort, merge…);
-
空间配置器(allocator);
-
配接器(stack, queue, priority_queue)。