函数模板

--------------------siwuxie095

  

  

  

  

  

  

  

  

  

函数模板

  

  

这里介绍函数模板,那么为什么要用函数模板呢?

  

  

  

  

看如下实例:

  

  

  

当要写一个比较大小的函数并返回较大的值时:

  

1)如果要比较两个int 类型的值,就写成第一个函数的形式

2)如果要比较两个float 类型的值,就写成第二个函数的形式

3)如果要比较两个char 类型的值,就写成第三个函数的形式

  

  

三个函数除了数据类型有所不同之外,它们的运算逻辑是完全相同的,

在这种情况下,如果我们要写上这三个函数,简直是太痛苦了,而且

做的工作也没有意义和价值

  

  

  

最好是能够有一种方案,即将类型作为参数传递进去,通过计算机

自动生成这三个函数,分别处理int 类型、float 类型、char 类型的

数据,并能根据传入的数据类型做相应的处理,取得相应的返回值

  

  

  

  

如果想这么做,我们需要三个关键字:templatetypenameclass

  

其中:

  

template,即 模板;而 typename 和 class 所起的作用是相同的

  

注意:这里的class 不是用来定义类的,而是用来表明数据类型的

  

  

  

通过class 来定义一个函数的模板:

  

  

  

当要定义函数模板时,需要通过 template 关键字来声明一个

函数模板,通过class 或 typename 关键字来声明一个参数,

该参数能表明一种数据类型

  

在写max() 函数时,返回值写上 T,参数用 T 来作参数类型,

而内部的逻辑不变

  

如果未来要传入的是int 类型的数据,计算机就会通过函数模板

实例化出一个模板函数,即T 全部被 int 取代,就能处理 int 类

型的数据了。如果未来要传入的是float 类型的数据,同理 …

  

  

  

在具体使用时:

  

  

  

当使用 max() 比较两个数据大小时,如果不指定数据类型 T,

计算机会根据自己的判断选择一种模板函数,选择之后就会

有自己的计算逻辑,如:int ival=max(100,99);,其中 100

和 99 都是 int 类型的,就会自动实例化一个 int 类型的模板

函数,然后对 100 99 进行处理,并将 100 返回出来,作

为返回值赋值给ival

  

如果指定了数据类型,如:char cval=max<char>('A','B');

在函数名后面用一对尖括号括起来,其中写明数据类型,就

指定传入的参数一定要是这种数据类型的参数才可以,然后

将返回值返回回来

  

  

  

函数模板 是函数的模具,通过模子就能一个一个的生产出

所谓的函数,也就是模板函数

  

在计算机中,如果仅仅写出了函数模板而没有使用它,计算机

是不会产生任何代码数据的,因为它也不知道要产生什么样的

代码数据

  

只有当使用函数模板时,计算机才知道具体要实例化出一个怎

样的模板函数,此时,才会产生真正的代码,参与逻辑的运行

  

  

  

  

通过 typename 来定义函数的模板:

  

  

  

swap() 是一个数据交换的函数,所使用的关键字除了 template 就是

typename,在使用上也没有什么不同,调用 swap(),这里指定的类

型是int,即 T 全部被 int 取代,那么传入的参数也必须是 int 类型的,

才能够处理

  

  

  

  

  

  

变量作为模板参数

  

  

看如下实例:

  

  

  

通过 template 关键字声明一个函数模板,这时,所传入的不再是类型,

而是个变量,该变量在真正去使用时,才会将函数模板实例化成一个模

板函数,它才是一个确定的值。如果不使用该函数模板,仍然没有任何

代码产生

  

使用时,传入的就不再是一个类型,而是一个确定的值,如:display<10>();

此时这个值其实就是一个常数,只不过在函数模板中体现出来的,看上去像是

一个变量,真正编译出来就是一个常数

  

  

  

  

  

  

多参数函数模板

  

  

模板有时会变的很复杂,因为我们不能确定在日常应用中,只有

一个类型作为模板的参数,如果有多个参数该如何处理呢?

  

  

看如下实例:

  

  

当有多个参数时,需要用逗号隔开,两个typename 都不能省略,

此时,T 和 C 都变成了函数模板的参数,在使用时,需要将T 和

C 的类型都指定出来,如:display<int,string>(a,str);

  

  

  

typename 和 class 所起的作用是一样的,所以在使用时,可以

混用,如下:

  

  

  

  

还可以这样来混用:typename 来定义数据类型 T,另外一个则是

变量 size,在使用时就可以指定 T 的数据类型和 size 的值,如下:

  

  

  

  

  

  

  

函数模板与重载

  

  

函数模板看上去就已经是一个重载的关系了,因为:通过函数模板

可以拓出无数个模板函数,我们可以尽情的去想象它能拓出的数据

类型,这些模板函数之间就形成了一种重载

  

此外,不同的函数模板所拓出的模板函数,也可能形成重载

  

看如下实例:

  

 

  

当前这三个函数模板,其实都有所不同,第一个函数模板只有 1 个参数,

第二个函数模板有两个参数,这就是参数的个数不同。第三个函数模板

也只有一个参数,看上去和第一个函数模板是一样的,但是第三个函数

模板的模板参数本身就有两个

  

  

  

在使用时:

  

  

  

通过三个不同的函数模板可以实例化出三个不同的模板函数,它们

之间就形成了重载

  

注意:当定义出函数模板时,函数模板本身并不是互相重载的关系,

因为在内存中,仅仅是将函数模板定义出来,并不能在内存中产生

出任何代码

  

只有在使用时,编译器才会产生相应的函数代码,产生函数代码后,

这些函数代码彼此之间才称得上是重载关系

  

  

  

  

程序:

  

main.cpp:

  

#include"stdlib.h"

#include <iostream>

using namespace std;

  

  

//template关键字声明一个模板 T是模板类型也是模板参数

template<typename T>

//此即为函数模板如果仅仅只是写出函数模板而没有使用它

//那么计算机是不会产生任何代码数据的因为它也不知道要产生什么样的代码数据

void display(T a)

{

cout << a << endl;

}

  

//使用了不同的关键字但意义一样(所起作用一样)可以混用

//推荐使用typename 毕竟class是类的关键字

template<typename T,class S>

void display(T t, S s)

{

cout << t << endl;

cout << s << endl;

}

  

  

//这里变量作为了模板参数KSize 此时传入的既有类型参数又有变量参数

template<typename T,int KSize>

void display(T t)

{

for (int i = 0; i < KSize;i++)

{

cout << t << endl;

}

}

int main(void)

{

//此即为模板函数:通过函数模板生产出来的函数也即实例化

//这时计算机才会产生真正的代码才会参与逻辑运行

display<char>('Q');

display<int, double>(5, 10.89);

display<int, 5>(9);

system("pause");

return0;

}

  

//同一函数模板生产出来的模板函数互为重载

//不同函数模板生产出来的模板函数也有可能互为重载

//

//在定义出函数模板的时候函数模板本身并不是互相重载的关系

//因为在内存当中我们仅仅将函数模板定义出来并不能在内存中产生出任何的代码

//

//只有在使用它们的时候编译器才会为我们产生出相应的函数代码来

//这些函数代码彼此间才称得上互为重载关系

  

  

  

  

  

  

  

  

  

【made by siwuxie095】

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值