C++ 函数模板

模板是C++泛型编程的基础。一个模板就是一个创建类或者函数的蓝图或者公式。通过提供有效的信息,我们将模板转换为特点的类或者函数,这个转换发生在编译过程


定义模板

假设我们需要一个函数来比较两个值的大小,并指出哪个值大。假如说我们需要比较两个整数谁比较大。那么有以下代码

int compare(const int &a,const int &b)
{
	if(a>b) return 1;
	if(b>a) return -1;
	return 0;
}

那么如果是我想比较两个string的大小呢?那会有如下代码

int compare(const string &a,const string &b)
{
	if(a>b) return 1;
	if(b>a) return -1;
	return 0;
}

这时候大家会发现一个问题,这两个函数几乎相同,唯一的不同是参数的差异,函数体完全一样。如果需要比较的类型少还好,如果所有类型都要比较的话,难道所有的都要写一遍?这不就是傻小子睡凉炕,全凭火力旺!
有没有改进措施?当然是有的,我们发现唯一不同的是参数,那么其实可以通过函数模板这种高效方法解决此问题。


函数模板

我们可以定义一个通用的函数模板,来供功能一样,参数不同的任务去使用。
一个函数模板就相当于一个公式,可以用来生成对应特定类型的函数版本
上面的任务可以写成下面的模板。

template <typename T>
int compare(const T &v1,const T &v2)
{
	if(v1>v2) return 1;
	if(v2>v1) return -1;
	return 0;
}

我们的compare函数声明了一个名为T的类型参数,在compare函数中,我们用T表示一个类型,而T表示的实际类型在编译时根据compare的使用情况来确定。

同时我们可以通过上面的例子,总结出函数模板的定义方式:

  • 模板定义以关键字template开始,后面跟一个模板参数列表
  • 在参数列表内部用逗号分隔开一个或多个列表。在模板定义中,模板参数列表不能为空
  • 在模板参数列表中,每一个类型参数前必须使用关键字class 或者 typename。这两个关键字的含义相同,可以互换使用,可以同时出现

其实我们可以发现,函数模板很像函数。我们通过实参来初始化函数中的形参,在这里我们用模板实参,“初始化”函数模板。


实例化函数模板

当我们调用一个函数模板时,编译器会用函数实参来为我们推断模板实参。也就是说,我们调用上面的compare函数时,编译器会根据我们给定的实参类型,来确定绑定到函数模板参数T的类型。

比方说在下面的例子中,实参类型是int,所以编译器也会推断出模板实参为int,并将它绑定到模板参数T上

cout<<compare(1,0)<<endl;

编译器推断出的模板参数会为我们实例化一个特定版本的函数。那么扩展一下,我们其实可以根据上面的模板,写出下面的代码

//vector<int> vec1{1,2,3}  vector<int> vec2{2,3,4}
cout<<compare(vec1,vec2)<<endl;

在这个例子中,我们实例化了一个,实参为vector的比较函数
这里我们的函数模板实例化方式是隐式实例化,对应的还有显式实例化


模板类型参数

我们可以利用函数模板中的类型参数,去指定返回类型,或者函数的参数类型,或者函数体内的变量声明或者类型转换。这里的类型参数可以看做类型说明符,就像内置类型或者类类型说明符一样使用。

template <typename T> T foo(T* p)
{
	T tmp = *p;//tmp的类型是指针p指向的类型
	...
	return tmp;
}

函数模板的重载

在c++中,重载不仅可以用在函数上,也可以用在函数模板上。下面的例子虽然只是给出了声明没有给实现,但是也可以发现,函数模板的重载与函数的重载一样,也是通过实参的数量,返回值类型等进行实现。

template<class T> void Swap(T &a, T &b);  //模板①:交换基本类型的值
template<typename T> void Swap(T a[], T b[], int len);  //模板②:交换两个数组
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值