8.5
8.5 函数模板
函数模板是通用的函数描述, 使用泛型来定义函数
其中的泛型可以用具体的类型替换, 通过类型作为函数参数传递给模板, 使编译器生成该类型的函数
C++函数模板功能能自动完成类型的替换过程:将所有int转换为double, 不会出现错误
允许以任意类型定义参数
template // AnyType可以任意选择, 遵守命名规则, 只对下一行的函数有效, 定义和声明前都要加上
void Swap(AnyType &a, AnyType &b)
{
AnyType temp;
temp = a;
a = b;
b = a;
}
template // C++98添加typename之前, 使用class
最终的代码不包含任何模板, 使用不同的参数, 就会出现不同的独立的函数定义
重载模板
和常规函数定义一样重载模板定义
重载
(T &, T &)
(T [], T [], int)
模板的局限性
对一些类型使用没有定义的运算符, 可能会出错。
重载运算符第11章
为特定的类型提供具体化的模板定义
显示具体化
struct job
{
char name[40];
double salary;
int floor;
};
第三代具体化
给定的函数名:非模板函数、模板函数、显式具体化模板函数和他们的重载版本。
显式具体化的原型和定义应以template<>打头, 并通过名称来指定类型
具体化优于常规模板, 非模板函数优于具体化和常规模板
void Swap(job &, job &); // 非模板函数
template // 模板函数
void Swap(T &, T &);
template<> void Swap(job &, job &); // 具体化, 可以省略, 相当于用模板函数指定了具体类型
实例化和具体化
函数模板本身不会生成函数定义
隐式实例化
只有在调用时, 指定了具体参数, 编译器才会生成一个模板实例。
显示实例化
template void Swap(int , int); // 使编译器生成一个使用int类型的实例。使用Swap模板生成一个int类型的函数定义
显示具体化
template<> void Swap(int &, int &);
template<> void Swap(int &, int &);
不要使用Swap模板生成函数定义, 应使用专门为int类型显示地定义的函数定义
当同一文件中使用显示实例化和显示具体化将会出错
int x = 10;
double m = 1.0;
Add(x, m); // 为类型double生成显示实例化。
统称为具体化
表示的都是使用具体类型的函数定义, 而不是通用描述。