C++之模板实例化

模板可以分为类模板与函数模板,它们的声明形式分别为:template<typename T1,typename T2,int Size> Class 类名;

                                                                                                        template<typename T1...> 返回值类型 函数名(形参表);

其中typename后跟的是类型参数,可以是内置类型,也可以是自定义类型,像Size这种为非类型参数,为固定值。

模板在没有被实例化的情况下是不会生成二进制代码的,其实例化分为三种方式,分别是:

1.隐式实例化

这种实例化是针对函数模板而言的,在发生函数调用时,编译器会先去寻找形参完全匹配的函数,如果没有找到,会对同名的函数模板进行推演,如果推演成功则隐式实例化该模板并完成调用,如果推演失败,则会去调用低一级的匹配函数,如下例所示。

#include<iostream>
using namespace std;
template <typename T>
void func(T t){
cout<<t<<endl;
}
template <typename T>
class A{
T num;
public:
A(){
num=T(6.8);
}
void invoke(void(*p)(T)){
p(num);
}
};
int main(){
A<int>a1;//类的显示模板实参
a1.invoke(func);//函数的隐式实例化
A<double>a2;
a2.invoke(func);
}

在主函数里两次调用了func函数,由于普通函数func的声明并不存在,只存在函数模板func的定义,因此会对func函数模板进行推演,若推演能获得成功,则将函数模板隐式实例化,在本例中分别将func模板隐式实例化为void func<int>(int t)及void func<double>(double t),编译后程序里将会存在这两个函数的二进制代码。

2.显示模板实参,下面给出一段程序。

#include <iostream>
using namespace std;
template <typename T> T Max (const T& t1,const T& t2){
return (t1>t2)?t1:t2;
}
int main(){
int i=5;
Max (i,'a');//调用失败
Max<int>(i,'a');//显示模板实参
}
直接调用函数Max(i,'a')会失败,这是因为i与‘a’具有不同的类型,在进行函数模板推演的时候会失败,而如果使用显示模板实参Max<int>(i,'a')则直接把模板实例化了,不需要再经过参数推演,并且char型参数'a'会隐式转化为int类型。

3.显式实例化

即在未发生函数调用的时候就将函数实例化,或者在为使用模板类时将类实例化,假设有函数模板template <typename T> void A (const T&)和类模板template <typename T> class B,则其显式实例化分别为:

函数模板的显式实例化:template void A<int> (const int&);

类模板的显式实例化:template class B<int>;

猜你喜欢

转载自blog.csdn.net/qq_36570733/article/details/78549505