首页 理论教育C++函数模板实例化

C++函数模板实例化

【摘要】:函数模板是不能直接执行的,需要实例化为模板函数后才能执行。模板函数的生成就是将函数模板的类型形参实例化的过程。当执行min时,便创建了该函数模板的一个实例,这个过程被称为函数模板实例化。图5.2函数模板的实例化在模板函数被实例化之前,必须在程序的某个地方首先声明它,这样,就可以到后面再实例化为模板函数。

函数模板是不能直接执行的,需要实例化为模板函数后才能执行。当编译系统发现有一个函数调用:

函数名(实参表);

C++将根据“实参表”中的类型生成一个重载函数,即模板函数。该模板函数的定义体与函数模板的函数定义体相同,而“形参表”的类型则以“实参表”的实际类型为依据。如以下语句实例化前面声明的函数模板:

abs(-10);

由于-10为int型,所以实例化为以下真正的模板函数:

再以-10为参数调用该模板函数,执行结果是返回10。

从上例看到,函数模板的数据类型参数标识符实际上是一个类型形参,在使用函数模板时,要将这个形参实例化为确定的数据类型。将类型形参实例化的参数称为模板实参,用模板实参实例化的函数就是模板函数。模板函数的生成就是将函数模板的类型形参实例化的过程。

【例5.1】分析以下程序的执行结果。

解:上述程序中,声明了一个函数模板Tmin(T x,T y),其作用是从函数参数的两个值中返回较小者。在main()中实例化为min(int,int)和min(double,double)两个模板函数。程序的执行结果如下:

较小整数:10

较小实数:5.6

对于比较两个整数和双精度型数的大小,传统做法要进行两次函数定义来处理这两次不同的调用。但这里将min()设计成模板,从而只要声明一次。当执行min(n1,n2)(第一次调用)时,便创建了该函数模板的一个实例,这个过程被称为函数模板实例化。生成的模板函数中两个变量的类型是int,int代替占位符T,这个模板函数可以比较两个整数的大小。当执行min(d1,d2)(第二次调用)时,创建该函数模板的第二个实例,生成的模板函数中两个变量的类型是double,这个函数用double代替了占位符T并且比较两个双精度数,其实例化如图5.2所示。

图5.2 函数模板的实例化(www.chuimin.cn)

在模板函数被实例化之前,必须在程序的某个地方首先声明它,这样,就可以到后面再实例化为模板函数。

模板函数有一个特点,虽然模板参数T可以实例化成各种类型,但是采用模板参数T的各参数之间必须保持完全一致的类型。模板类型并不具有隐式的类型转换,例如在int与char之间、float与int之间、fIoat与double之间等的隐式类型转换。而这种转换在C++中是非常普遍的。

【例5.2】分析以下程序中的错误。

解:上述程序中,main()函数中的最后3个语句在编译时出现错误,原因是min模板参数T的各参数之间必须保持完全一致的类型,但这3个语句的实参的类型与形参不一致,如min(n,c),系统找不到与max(int,char)相匹配的函数定义,虽然int和char之间可以隐式转换,完全可以认为是max(int,int),但是模板类型没有这种识别能力。

【例5.3】编写一个对具有n个元素的数组a[]求最小值的程序,要求将求最小值的函数设计成函数模板。

解:设计函数模板ArrayMin用于求一个数组的最小值,在main函数中对其实例化。程序如下:

程序的执行结果如下:

a数组的最小值为:-12

b数组的最小值为:-9.8

【例5.4】分析以下程序的执行结果。

解:上述程序中,设计了一个函数模板sort,它采用冒泡排序法排序对p所指元素到q所指元素之间的所有元素进行部分排序。在main函数中,实例化该函数模板对数组a中的前4个元素进行排序。程序执行结果如下:

4 19 43 54 60 70 81 2 14 0