显式实例化,相当于通知编译器接下来我要使用这种数据类型的函数,显示的通知编译器生成对应的模板,以此和隐式的实例化相区别,隐式的实例化通过实参的类型来控制编译器对于通用函数模板相应类型的生成,而显式实例化为明文通知,实际效果上两者似乎并无太大区别。函数实例化有点类似于java泛型中的向下转型:
template <typename T> T Add(T a, T b) {
return a + b
}
int m = 6;
int n = 10.2;
cout << Add<double>(m, n); //这里通过了在程序中使用函数来创建显式实例化
将原本不匹配的函数模板强制为doublle类型实例化。
显示具体化类似于泛型函数对于某一特定类型的重载,在已经实现了泛型函数的情况下,需要对某一特定类型的函数进行定制,则使用显示具体化来实现该函数。显式实例化不需要写函数的具体实现(函数定义),而显式具体化必须要实现。
显式实例化和显式具体化在形式上主要体现在声明形式的不同。另外显式具体化要实现具体的函数定义。
函数实例化:
template void Swap<int>(int &, int &);
显式具体化:
template <> void Swap(int &, int &);
//或者 template <> void Swap<int>(int &, int &);
...
template <> void Swap<int>(int &, int &) {
函数定义
}
在使用中,如果一个函数适应多种原型,则非模板版本优先于显式具体化版本,显式具体化版本优先于模板生成版本,这里的模板生成版本包括显示和隐式的实例化。