隐式实例化
当我们写好了一个函数模板,但实际上它只是一个编译指令,只有当我们用的时候,才会根据函数模板去生成具体的函数,而什么时候用取决于使用者。这也就是隐式实例化。
template<typename T>
T add(T a, T b)
{
return a+b;
}
int main()
{
double a=2.5;
double b=3.5;
cout<<"a+b="<<add(a,b)<<endl; // 模板实参推断
cout<<"a+b="<<add<int>(a,b); // 显式指定参数类型
}
显式实例化
显式实例化与前面的隐式实例化不同的是:实例化的时机不同。在我们写好一个函数模板后,如果我们能确定某个函数在接下来的业务逻辑中一定会被用到,则我们可以在这时候抢先实例化出这个函数。这样就比较快速,从而省去运行阶段创建这个函数的时间。
template<typename T>
void Swap(T&, T&)
{
T temp;
temp=a;
a=b;
b=temp;
}
template void Swap<int>(int&,int&);
int main()
{
//.................
.......代码段........//
}
当使用关键字template并指出所需类型来声明类时,编译器将生成函数声明的实例化。声明必须位于模板定义所在的作用域中。虽然没有创建或提及函数对象,编译器也将生成函数声明(包括方法定义)。但是,在实际使用时,会提示找不到Swap函数定义。
特例化
有时候,尽管你的模板支持int,double,float,char…等等数据类型,但是等到下文去用的时候发现,虽然这个模板可以处理百分之九十的东西,但是总是存在一些例外是前文定义的模板所不能支持的,诚然,这个时候我们就要特殊情况特殊处理了。这种特殊情况特殊处理的方式就是C++里的特例化。
有时候,可能需要在为特殊类型实例化时,对模板进行修改,使其行为不同。在这种情况下,可以提供一个模板特例化。当特例化模板和通用模板都与实例化请求匹配时,编译器将优先使用特例化版本。
// 通用模板
template<typename T>
void Swap(T&, T&)
{
T temp;
temp=a;
a=b;
b=temp;
}
// 特例化模板
struct job
{
char name[Max];
double salary;
int floor;
};
template <> void Swap(job& a, job& b)
{
int temp1;
temp1 = a.floor;
a.floor = b.floor;
b.floor = temp1;
//
double temp2;
temp2 = a.salary;
a.salary = b.salary;
b.salary = temp2;
}
部分特例化(只有类模板可用)
部分特例化也是特例化的一种方式。处理的场景也跟前面差不多。那么为什么叫部分特例化呢?前面的特例化里,我们的模板参数只有一个,如果我们对其进行特例化,就相当于对全部参数进行特例化;但是也有一些情况,我们会遇到需要多个参数的模板。而我们的使用场景可能仅仅需要我们对个别参数进行特殊处理,这时候我们就可以通过部分特例化,部分限制模板的通用性,仅对部分数据进行特殊处理:
//general template
template<class T1,class T2,class T3> class Trio{...};
//specialization with T3 set to T2
template<class T1,class T2> class Trio<T1,T2,T2>{...};
//specialization with T3 and T2 set to T1*
template<class T1> class Trio<T1,T1*,T1*>{...};
//给出上述声明,编译器将作出以下选择:
Trio<int,short,char*> t1;//use general template
Trio<int,short> t2;//use Trio<T1,T2,T2>
Trio<char,char*,char*> t3;//use Trio<T1,T1*.T1*>
编译器重载规则
一般来说调用函数的优先级:非模板函数 > 特例化的模板函数 > 通用模板函数。
Swap(e1,e2); // 优先使用非模板函数
Swap<int>(f1,f2); // 使用模板函数
特别地,加上尖括号相当隐式实例化,让编译器使用模板函数而不是非模板函数。
参考文献
https://blog.csdn.net/qq_41126898/article/details/114503219
https://blog.csdn.net/weixin_43717839/article/details/131320956
C++ Primer(第五版)