函数模板格式
在C++98添加关键字typename之前,C++使用关键字class创建模板。class和typename使用哪个都可以,一般使用typename。
template <class/typename T>void Swap(T &a, T &b){T temp;temp = a;a = b;b = temp;}
重载的模板
template <typename T>void Swap(T &a, T &b);template <typename T>voido Swap(T *a, T *b, int n);
显示具体化(explict specialization)
- 对于给定的函数名,可以有非模板函数、模板函数和显式具体化模板函数以及它们的重载版本。
- 显示具体化的原型和定义应以template<>打头,并通过名称来指定类型。
- 具体化优先于常规模板,而非模板函数优先于具体化和常规模板
以下是交换函数Swap非模板函数、模板函数和具体化原型
struct job{char name[40];double salary;int floor;};//非模板函数void Swap(job &, job &);//模板函数template <typename T>void Swap (T &, T &);//显示具体化 --- 以下两种方式都可以template <> void Swap<job>(job &, job &);template <> void Swap(job &, job &);
例子:
#include <iostream>//函数模板template <typename T>void Swap(T &a, T &b);//显示具体化template <> void Swap<int>(int &a, int &b);template <typename T>void Swap(T &a, T &b){T temp;temp = a;a = b;b = temp;}template <> void Swap<int>(int &a, int &b){int temp;temp = a;a = b;b = temp;}int main(){int x1 = 2, x2 = 3;Swap(x1, x2); //调用显示具体化std::cout << "x1:" << x1 << std::endl;std::cout << "x2:" << x2 << std::endl;std::string a1 = "123";std::string a2 = "111";Swap(a1, a2);std::cout << "a1:" << a1 << std::endl;std::cout << "a2:" << a2 << std::endl;return 0;}
实例化
在代码中包含函数模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。编译器使用函数模板为特定类型生成函数定义时,得到的是模板实例。
最初编译器只能通过隐式实例化,来使用模板生成函数定义,也可以显示实例化一个函数定义。
语法:
//实际使用中只需要在使用的位置,声明下就可以, 无需添加额外的定义;//以Swap函数为例template void Swap<int>(int, int);
注:试图在同一文件中使用同一类型的显示实例和具体化将出错
