C++——函数模板 – 作者:Johnson666

函数模板的定义

函数模板定义的一般形式如下:

template<类型形式参数表> 返回类型 函数名(形式参数表)
{
    //函数体
}

template为关键字,表示定义一个模板,尖括号<>表示模板参数,模板参数主要有两种,一种是模板类型参数,另一种是模板非类型参数。上述代码中定义的模板使用的是模板类型参数,模板类型参数使用关键字class或typedef开始,其后是一个用户定义的合法标识符。模板非类型参数与普通参数定义相同,通常为一个常数。
可以将声明函数模板分成template部分和函数名部分。例如:

template<class T>
void fun(T t)
{
    //函数实现
}

定义一个求和的函数模板,例如:

template<class type>
type Sum(type xvar,type yvar)
{
    return xvar + yvar;
}

在定义完函数模板之后,需要在程序中调用函数模板。下面的代码演示了Sum函数模板的调用。

int iret = Sum(10,20);
double dret = Sum(10.5,20.5);

如果采用如下的形式调用Sum函数模板,将会出现错误。

int iret=Sum(10.5,20);
double dret=Sum(10,20.5);

上述代码中为函数模板传递了两个类型不同的参数,编译器产生了歧义。如果用户在调用函数模板时显式标识模板类型,就不会出现错误了。例如:

int iret=Sum<int>(10.5,20);
double dret=Sum<double>(10,20.5);

用函数模板生成实际可执行的函数又称为模板函数。函数模板与模板函数不是一个概念。从本质上讲,函数模板是一个“框架”,它不是真正可以编译生成代码的程序,而模板函数是把函数模板中的类型参数实例化后生成的函数,它和普通函数本质是相同的,可以生成可执行代码。

函数模板的作用

假设求两个函数之中的最大者,如果想求整型数和实型数需要定义两个函数,两个函数定义如下:

int max(int a, int b)
{
    return a>b?a:b;
}
float max(float a,float b)
{
    return a>b?a:b;
}

能不能通过一个max函数来完成既求整型数之间最大者又求实型数之间最大者呢?答案是使用函数模板以及#define宏定义。

#define宏定义可以在预编译期对代码进行替换。例如:

#define max(a,b)((a)>(b)?(a):(b))

上述代码可以求整数最大值和实型数最大值。但宏定义#define只是进行简单替换,它无法对类型进行检查,有时计算结果可能不是预计的,例如:

#include <iostream>
#include <iomanip>

using namespace std;

#define max(a,b)((a)>(b)?(a):(b))

void main()
{
	int m = 0, n = 0;
	cout << max(m, ++n) << endl;
	cout << m << setw(2) << endl;
}

结果:
image.png
程序的预期结果应该是1和0,为什么输出2和0这样的结果呢?原因在于宏替换之后++n被执行了两次,因此n的值是2而不是1.

使用数组作为模板参数:

#include <iostream>

using namespace std;

template<class type, int len>

type Max(type array[len])
{
	type ret = array[0];
	for(int i = 1; i < len; i++)
	{
		ret = (ret > array[i]) ? ret : array[i];
	}
	return ret;
}

void main()
{
	int array[5] = {1, 2, 3, 4, 5};
	int iret = Max<int, 5>(array);
	double dset[3] = {10.5, 11.2, 9.8};
	double dret = Max<double, 3>(dset);
	cout << dret << endl;
}

结果:
image.png
程序中定义一个函数模板Max,用来求数组中元素的最大值,其中模板参数使用模板类型参数type和模板非类型参数len,参数type声明了数组中的元素类型,参数len声明了数组中的元素个数,给定数组元素后,程序将数组中的最大值输出。

重载函数模板

整型数和实型数编译器可以直接进行比较,所以使用函数模板后也可以直接进行比较,但是如果是字符指针指向的字符串该如何比较呢?答案是通过重载函数模板来实现。通常字符串需要库函数来进行比较,通过重载函数模板实现字符串的比较。

求出字符串的最小值:

#include <iostream>
#include <string>

using namespace std;

template<class Type>

Type min(Type a, Type b)
{
	if(a < b)
		return a;
	else
		return b;
}

char *min(char *a, char *b)
{
	if(strcmp(a, b))
		return b;
	else
		return a;
}

void main()
{
	cout << "最小值" << min(10, 1) << endl;
	cout << "最小值" << min('a', 'b') << endl;
	cout << "最小值" << min("hi", "mr") << endl;
}

结果:
image.png
程序在重载的函数模板min的实现中,使用strcmp库函数来完成字符串的比较,此时使用min函数可以比较整型数据、实型数据、字符数据和字符串数据。

来源:freebuf.com 2021-06-29 15:31:28 by: Johnson666

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论