1. 实例化(instantiation)
实例化是指编译器使用函数(或者是类)模板为特定类型生成函数(类)定义。编译器不会为函数(或者类)模板生成定义,只有当我们为函数(或者类)模板指定了一个特定类型时,编译器才会生成。编译器为特定类型的函数(或者类)模板生成定义的行为被称为实例化。
template<typename T>
void Swap(T & a, T & b)
{
T temp = a;
a = b;
b = temp;
}
void use_Swap(int & a, int & b)
{
Swap(a, b);
}
举个例子,上面这段代码,通过反汇编的结果如下:
_Z4SwapIiEvRT_S1_:
pushq %rbp
movq %rsp, %rbp
... ...
ret
Z4SwapIiEvRT_S1:对应的函数声明为void Swap(int&, int&),因此可以看到编译器实例化了Swap模板函数,这种实例化方法被称为隐式实例化。如果注释掉use_Swap函数,通过反汇编可以发现编译器不会实例化Swap函数,因为此时代码中只有Swap的模板函数,而没有为该函数指定一个特定类型的版本。
c++可以显示实例化一个模板函数(或者类)。
template void Swap<int>(int & a, int & b); /* 显示实例化Swap函数 */
2. 具体化(specialization)
使用模板能够极大的精简我们的代码量,尤其是在容器类或者一些通用函数中。但是,模板不能帮助我们解决所有问题。有时候我们需要针对特定的场景提供一个特殊的函数(或者类)定义,这个就是具体化。要注意实例化的具体化的区别,可以从编译器的角度来看这两者之间的区别,实例化是指编译器生成特定函数(或者类)定义;而具体化可以看做是一个特殊版本的用来生成函数(或者类)定义的方案,它只是一个方案,因此编译器不会生成定义。
struct ST;
/* 显示具体化的原型和定义应以template <> 开头 */
template <> void Swap<ST>(ST & st1, ST & st2);
上面是针对ST类型的Swap模板函数的一个显示具体化。模板类的实例化如下所示。
template<typename T>
class Swap {...};
template <> class Swap<ST> {...};
3. 部分具体化(partial specialization)
c++还允许部分具体化。template后面<>声明的是没有被具体化的参数类型。如果<>里面是空的,将导致显示具体化。
template<typename T1, typename T2>
class Swap {...};
template <typename T1> class Swap<T1, int> {...};
下面也是一种部分具体化的形式,表示该具体化版本只适用于T为原生指针的情况。
template<typename T>
class C<T*> {...};