大家好,上次我们讲了模板编程的好处,它的好处主要是实现数据类型和逻辑代码相分离,从而实现代码的高度复用。这次,我们就来看一下如何在C++中定义一个函数模板,通过函数模板实现算法与数据类型相分离。
首先,请让我介绍一下什么是函数模板?
函数模板是C++模板机制中的一种,主要的目标是将函数的数据类型和逻辑代码相分离,从而实现代码的高度复用。函数模板也可以理解为是一种通用函数,这个通用函数的参数和返回值的数据类型可以不必具体指定,而是用一个假设的类型来表示,只有当函数模板实例化的时候,才会用具体的数据类型来代替这个假设的数据类型。
下面,我们来看一下,在C++中如何定义一个函数模板?
函数模板以关键字template开头,其后是一对尖括号划分的模板参数列表。模板参数列表中可以声明多个模板参数,多个参数声明之间以逗号分隔。当我们调用它的时候和调用普通函数一样,唯一的不同是需要在函数名后追加一对尖括号,并在尖括号中指定模板函数的具体数据类型。下面,请让我们来看一个例子,通过这个例子,帮助大家理解函数模板的定义和使用方法。
例1 实现一个函数,在不同类型的数组中找到最大值。
函数功能:在数组中寻找最大值
函数参数:
input:数组首地址
nLen:数组长度
max:数组中的最大值,是一个输出参数
函数返回:成功返回1,失败返回0
#include<stdio.h>#include<stdlib.h>运行效果如下:
template<typename T>
int max_element(T * input,int nLen, T & max)
{
if (!input)
{
return 0;
}
int i = 0;
max = input[0];
for (i = 1; i < nLen; i++)
{
if (max < input[i])
{
max = input[i];
}
}
return 1;
}
void main()
{
int nArray[5] = { 9, 6, 3, 8, 5 };
float fArray[5] = { 9.3, 8.2, 4.5, 1.6, 7.4 };
char cArray[5] = { 'a', 'c', 'g', 'e', 'h' };
int nMax = 0;
float fMax = 0.0f;
char cMax = 0;
if (!max_element<int>(nArray, 5, nMax))
{
printf("求最大值失败.\n");
}
else
{
printf("整数数组中的最大值:%d\n", nMax);
}
if (!max_element<float>(fArray, 5, fMax))
{
printf("求最大值失败.\n");
}
else
{
printf("浮点数组中的最大值:%.2f\n", fMax);
}
if (!max_element<char>(cArray, 5, cMax))
{
printf("求最大值失败.\n");
}
else
{
printf("字符数组中的最大值:%c\n", cMax);
}
return;
}
例1中定义了一个函数模板max_element,它的形参中input和max的数据类型并没有具体指定,而是用一个假设的虚拟数据类型T来表示,当我们在main函数中调用它的时候,需要在模板函数名后追加一对尖括号,在尖括号中为函数模板制定具体的数据类型,比如,在我们的例子中,先后分别指定了int,float,char,这样这三个模板函数就会被具现为3个函数,这3个函数的参数类型先后分别是int,float,char。
在例1中,我们讲解了如何定义一个函数模板,以及如何使用它,但是它的模板参数只有1个,这样很有可能会让很多读者误会为函数模板的参数只能有1个,其实,不是这样的。下面我们就来举个例子,告诉大家如何定义一个具有多个模板参数的函数模板。
例2 定义一个函数模板,打印函数参数类型尺寸的最大值。
函数功能:打印函数参数类型尺寸的最大值
函数参数:
input1:参数1,随便指定一个值就可以,只要它是T1类型
input2:参数2,随便指定一个值就可以,只要它是T2类型
input3:参数3,随便指定一个值就可以,只要它是T3类型
函数返回:返回参数类型尺寸的最大值
#include<stdio.h>#include<stdlib.h>template<typename T1,typename T2,typename T3>int max_type_size(T1 input1, T2 input2, T3 input3){int nSize = sizeof(input1);if (nSize < sizeof(input2)){nSize = sizeof(input2);}if (nSize < sizeof(input3)){nSize = sizeof(input3);}return nSize;}void main(){int nMaxSize = 0;nMaxSize = max_type_size<char, int, double>('1', 1, 1.0);printf("参数类型最大尺寸为:%d\n", nMaxSize);return;}运行效果如下:
在例2中,我们定义了一个函数模板max_type_size,它有3个模板参数,当我们调用它的时候,会计算出这3个模板参数类型的最大值。
需要注意的一点是:T2和T3前面的typename不能省略,否则会编译错误。
今天,我们主要讲解了如何定义和使用函数模板,并举了2个例子,通过例子告诉大家如何定义单个模板参数和多个模板参数的函数模板以及需要注意的事项。