函数模板与泛型,隐式实例化、显示实例化、显示具体化
关于函数模板与泛型编程的关系,见
https://blog.csdn.net/baidu_37964071/article/details/78235247
函数模板是通用的函数描述,它们使用泛型来定义函数,其中的泛型可用具体的类型(如int 或 double)替换。
1.模板并不创建任何函数,只告诉编译器应该如何定义函数;函数模板不能缩短可执行程序,最终的代码不包含任何模板,而只包含为了程序生成的实际函数。(c++pp page 231)
2.显示具体化:为特定类型提供具体化的模板定义,优先级高于函数模板;(c++pp page 234);而非模板函数高于显示具体化和模板函数。
3.显示实例化:定义好函数模板后,当程序需要该函数模板定义的具体类型的函数时,编译器会根据该函数模板生成具体类型的函数定义,这种实例化方式被称为隐式实例化;
但c++还允许显示实例化。
模板函数:
template <class T> void Swap(T &,T &);//template <typename T> void Swap(T &,T &);
显示实例化:
template void Swap<int>(int &,int &);
显示具体化:
template <> void Swap<int>(int& , int&); template <> void Swap(int& , int&);
显示具体化的使用:
使用显示具体化之前,必须有一个与其对应的模板函数,这一点与显示实例化类似,只不过显示实例化不需重新定义,因为其只是显示的实例化一个模板;而显示具体化需要重新定义,因为其要凸显与模板函数定义不同的地方,若显示具体化的定义与其对应的模板函数相同,则也没有必要使用显示具体化了。
显示实例化的使用:
当显示实例化模板时,在使用模板之前,编译器根据显示实例化指定的类型生成模板示例。
显示实例化只需声明,不需重新定义;编译器根据模板实现示例声明和示例定义。(参考:https://codeantenna.com/a/wpQy4vME47,c++ pp page 236)
#include <iostream> using namespace std; template <typename T>//模板声明 void Swap(T&,T&); template<> //显示具体化声明,具体化Swap这个模板函数 void Swap<double>(double& a,double& b);//显示实例化声明 template void Swap <char>(char& ,char& ); int main() { int a = 1; int b = 2; double c = 3.1; double d = 4.1; char e = 'a'; char f = 'b'; Swap(a,b);//使用模板函数,隐式示例化生成关于具体的int类型的函数定义 Swap(c,d);//使用显示具体化声明 Swap(e,f);//使用显示实例化 return 0; } template <typename T>//模板定义 void Swap(T& a,T& b) { T temp = a; a = b; b = temp; cout<<"T"<<endl; } template<> //显示具体化定义,凸显与Swap模板函数不同的地方 void Swap<double>(double& a,double& b) { double temp = a; a = b; b = temp; cout<<"double"<<endl; }