函数模板格式
在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);
注:试图在同一文件中使用同一类型的显示实例和具体化将出错