C++中函数模板与模板函数

  • 模板说明
    为了定义函数模板,首先要进行模板说明,其作用是说明模板中使用的类属参数。模板说明有形式有两种:
template <class T1, class T2, ... class Tn>
//或者是:
template<typename T1, typename T2, ... typename Tn> 

  为了增强程序的可读性,建议使用关键字typename。关键字template表示正在说明一个模板,而T1,T2,...Tn是等待实例化的类属参数。它们所对应的实际参数可以是int、double、char等基本类型,也可以是指针、类等各种用户已经定义的类型。

函数模板

  • 假设我们要写一个函数,比较两个整数的最大值,正确代码如下:
int Max(int a, int b)
{
	return a > b? a : b;
}

  如果我们还要比较两个double类型,float等类型的最大值,那我们就需要继续写参数和返回值不同,而实现功能相同的函数。这样的话会显得很繁琐。浪费时间~~

  • 那我们可不可以只用一个函数来实现不同数值类型之间的最大值比较?答案是可以的。我们可以用模板来实现。具体代码如下:
template<typename T>
T Max(const T a, const T b)
{
	return a > b? a : b;
}

  在上面代码中,当程序调用Max函数时,编译器会根据传递给函数Max的参数来自动判断形式参数ab的数值类型,
  我们可以用下面函数调用Max函数证明:

int main()
{
	int x1 = 5, x2 = 6;
	cout<<"第一次调用后的结果为:"<<Max(x1, x2)<<endl;
	double x3 = 4.8, x4 = 5.9;
	cout<<"第二次调用后的结果为:"<<Max(x3, x4)<<endl;
}

运行结果为:

第一次调用后的结果为:6
第二次调用后的结果为:5.9

  • 我们可以看到,两次调用Max函数,传递的参数类型都不相同,但是程序依然可以正常运行。这是因为两次调用都分别给函数进行不同的实例化。下图给出了函数模板和模板函数的关系示意图。这些重载函数,通过函数模板按实际类型生成,所以称为模板函数,而这个过程称为实例化
    函数模板与模板函数的关系

重载函数模板

1. 函数模板重载

  • 重载函数模板便于定义类属参数,或者由于函数参数的类型、个数不同所进行的类似操作,比如上面Max函数是返回两个数的最大值,我们可以将Max函数模板重载为求数组最大元素的函数模板。具体代码如下:
template<typename T>
T Max(T *a, int n)
{
	T temp = a[0];
	for(int i = 1; i < n; i++)
	{
		temp = temp > a[i]? temp : a[i];
	}
}

2. 用普通函数重载函数模板

  • 函数模板实例化的时候,实际参数类型替换类属参数。具有类型检查功能,却没有普通传值参数类型转换机制。例如:当调用第一个Max函数比较两个值大小时,两个实际参数必须类型相同。若用以下调用,则编译器会报错
int main()
{
	int k = 3; double c = 2.9;
	Max(k, c);
}
  • 当用以下函数重载Max函数时,再用上面调用方式,则不会发生报错
int Max(int a, double b)
	return a > b? a : b;

  重载函数int Max(int a, double b)可以隐式进行数据类型转换。

  • 如果重载函数改为:
int Max(int a, int b)
	return a > b? a : b;

  则不同的编译器可能导致不同的结果(一般都会报错)。

编译器通过匹配过程确定调用哪个哪个函数。匹配顺序如下:

  1. 寻找和使用最符合函数名和参数类型的函数,若找到,则使用他;
  2. 否则,寻找一个函数模板,将其实例化,产生一个匹配的模板函数,若找到,则调用它;
  3. 否则,寻找可以通过类型转换进行参数匹配的重载函数,若找到,则使用它。

如果按以上步骤均未能找到匹配函数,则这个调用是错误的;如果这个调用有多于一个的匹配选择,则调用匹配产生二义性,也是错误的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L丶丨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值