C++函数模板

我们知道,数据或数值可以通过函数参数传递,在函数定义时它们是未知的,只有在发生函数调用时才能确定其值。这就是数据的参数化。

其实,数据类型也可以通过参数来传递,在函数定义是可以不指明具体的数据类型,当发生函数调用时,编译器可以根据传入的参数自动确定数据类型。这就是数据类型参数化。

所谓函数模板,实际上是建立一个通用函数,其返回值类型和形参类型不具体指定,用一个虚拟的类型来代替(实际上是用一个标识符来占位)。这个通用函数就称为函数模板(Function Template)。凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会用实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。

【例】将上节代码改为通过函数模板来实现。

#include

using namespace std;

template //模板声明,其中T为类型参数

T max(T a, T b, T c) //定义一个通用函数,用T作虚拟的类型名

{

if(b>a) a=b;

if(c>a) a=c;

return a;

}

int main( )

{

//求三个整数的最大值

int i1, i2, i3, i_max;

cin >> i1 >> i2 >> i3;

i_max = max(i1,i2,i3);

cout << "i_max=" << i_max << endl;

//求三个浮点数的最大值

double d1, d2, d3, d_max;

cin >> d1 >> d2 >> d3;

d_max = max(d1,d2,d3);

cout << "d_max=" << d_max << endl;

//求三个长整型数的最大值

long g1, g2, g3, g_max;

cin >> g1 >> g2 >> g3;

g_max = max(g1,g2,g3);

cout << "g_max=" << g_max << endl;

}

运行结果与上节相同。

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

template < typename T>

通用函数定义  通用函数定义

template

通用函数定义  通用函数定义

在建立函数模板时,只要将例4.5程序中定义的第一个函数首部的int改为T即可。即用虚拟的类型名T代替具体的数据类型。在对程序进行编译时,遇到第13行调用函数max(i1, i2, i3),编译系统会将函数名max与模板max相匹配,将实参的类型取代了函数模板中的虚拟类型T。此时相当于已定义了一个函数:

int max(int a, int b, int c)

{

if(b>a) a=b;

if(c>a) a=c;

return a;

}

然后调用它。后面两行(14,15行)的情况类似。

类型参数可以不只一个,可以根据需要确定个数。如:

template

可以看到,用函数模板比函数重载更方便,程序更简洁。但应注意它只适用于函数的参数个数相同而类型不同,且函数体相同的情况,如果参数的个数不同,则不能用函数模板。

C++函数的默认参数

一般情况下,在函数调用时形参从实参那里取得值,因此实参的个数应与形参相同。有时多次调用同一函数时用同样的实参,C++提供简单的处理办法,给形参一个默认值,这样形参就不必一定要从实参取值了。如有一函数声明:

float area(float r=6.5);

指定r的默认值为6.5,如果在调用此函数时,确认r的值为6.5,则可以不必给出实参的值,如:

area( ); //相当于area(6.5);

如果不想使形参取此默认值,则通过实参另行给出。如:

area(7.5); //形参得到的值为7.5,而不是6.5

这种方法比较灵活,可以简化编程,提高运行效率。

如果有多个形参,可以使每个形参有一个默认值,也可以只对一部分形参指定默认值,另一部分形参不指定默认值。如有一个求圆柱体体积的函数,形参h代表圆柱体的高,r为圆柱体半径。函数原型如下:

float volume(float h, float r=12.5); //只对形参r指定默认值12.5

函数调用可以采用以下形式:

volume(45.6); //相当于volume(45.6,12.5)

volume(34.2, 10.4); //h的值为34.2,r的值为10.4

实参与形参的结合是从左至右顺序进行的。因此指定默认值的参数必须放在形参表列中的最右端,否则出错。例如:

void f1(float a, int b=0, int c, char d=′a′); //不正确

void f2(float a, int c, int b=0, char d=′a′); //正确

如果调用上面的f2函数,可以采取下面的形式:

f2(3.5, 5, 3, ′x′) //形参的值全部从实参得到

f2(3.5, 5, 3) //最后一个形参的值取默认值′a′

f2(3.5, 5) //最后两个形参的值取默认值,b=0,d=′a′

可以看到,在调用有默认参数的函数时,实参的个数可以与形参的个数不同,实参未给定的,从形参的默认值得到值。利用这一特性,可以使函数的使用更加灵活。例如例4.7求2个数或3个数中的最大数。也可以不用重载函数,而改用带有默认参数的函数。

【例】求2个或3个正整数中的最大数,用带有默认参数的函数实现。

#include

using namespace std;

int main( )

{

int max(int a, int b, int c=0);//函数声明,形参c有默认值

int a,b,c;

cin>>a>>b>>c;

cout<

cout<

return 0;

}

int max(int a,int b,int c) //函数定义

{

if(b>a) a=b;

if(c>a) a=c;

return a;

}

运行情况如下:

14 -56 135↙

max(a,b,c)=135

max(a,b)=14

在使用带有默认参数的函数时有两点要注意:

如果函数的定义在函数调用之前,则应在函数定义中给出默认值。如果函数的定义在函数调用之后,则在函数调用之前需要有函数声明,此时必须在函数声明中给出默认值,在函数定义时可以不给出默认值(如例4.8)。

一个函数不能既作为重载函数,又作为有默认参数的函数。因为当调用函数时如果少写一个参数,系统无法判定是利用重载函数还是利用默认参数的函数,出现二义性,系统无法执行。

c 语言 模板函数参数,深入解析C++中的函数模板和函数的默认参数相关推荐

  1. 自己实现c语言itoa函数_在C / C ++中实现itoa()函数

    自己实现c语言itoa函数 In this article, we'll take a look at implementing the itoa() function in C/C++. 在本文中, ...

  2. c语言strdup函数_在C / C ++中使用strdup()函数的指南

    c语言strdup函数 In this article, we'll take a look at using the strdup() function in C/C++. 在本文中,我们将研究在C ...

  3. 源码解析glibc中的pclose与fclose函数

    文章目录 pclose 和 fclose 的阻塞问题 测试代码 问题 pclose与fclose的关系 fclose函数的定义 pclose函数的定义 总结 fclose中的block 有嫌疑的地方 ...

  4. 解析Unity3D中计算法线矩阵的函数

    如果法线简单地跟着顶点变换有时会出现如下图情况, 若图2所示,垂直关系变了. 可以用线性代数知识证明 设原来的切线为 T T T,法线 N N N,则有 T T N = 0 T^TN=0 TTN=0 ...

  5. 在php中函数名称区分大小写吗,PHP中的变量名,函数名,类名是区分大小写的吗...

    在javascript中关于变量与函数的提升 在javascript中关于变量与函数的提升 一.简介 在javascript中声明变量与函数的执行步骤: 1.先预解析变量或函数声明代码,会把用var声 ...

  6. java请求参数_在Java中发送http的post请求,设置请求参数等等

    前几天做了一个定时导入数据的接口,需要发送http请求,第一次做这种的需求,特地记一下子, 导包 import java.text.SimpleDateFormat; import java.util ...

  7. pythoncopy函数_Python的shutil模块中文件的复制操作函数详解

    copy()chutil.copy(source, destination) shutil.copy() 函数实现文件复制功能,将 source 文件复制到 destination 文件夹中,两个参数 ...

  8. c语言中sprintf函数_在C / C ++中使用sprintf()函数

    c语言中sprintf函数 In this article, we'll take a look at using the sprintf() function in C / C++. 在本文中,我们 ...

  9. python中延时函数_详解python中实现延时回调普通函数

    这篇文章主要给大家介绍了关于python中实现延时回调普通函数的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧. 前言 ...

最新文章

  1. 股权分配中的三种定时炸弹
  2. win10 + mac双系统安装常用工具
  3. 大剑无锋之Zookeeper面试题
  4. 循环卷积和周期卷积的关系_基于单口RAM读写的卷积电路(下)
  5. netty权威指南第三版_Hadoop权威指南(第二版及第三版)
  6. 4种操作符的区别和联系
  7. Ueditor编辑器任意文件上传漏洞
  8. keep 虚拟路线修改器_从初音未来到歌王子殿下,尚未VTuber化的虚拟偶像
  9. php计算股票均线,php写智能选股,股票回测系统之--MACD指标计算方法及实例
  10. Ubuntu垃圾箱目录及清空
  11. 海洋大数据应用关键技术及应用前景
  12. [渝粤教育] 泰州学院 信息技术基础 参考 资料
  13. 业务流程再造和IT服务能力
  14. 计步器算法简述和模块使用
  15. mac运行.py提示缺少模块的解决方法
  16. URL伪静态。SEO中理解伪静态
  17. 如何修改PyCharm窗口背景颜色?
  18. 中职计算机基础教材节选,中职计算机基础 (985)(33页)-原创力文档
  19. 18.缓存预热、缓存雪崩、缓存击穿、缓存穿透、性能指标监控等企业级解决方案
  20. 【ESP 保姆级教程】 自定义库篇 ——FeiShuMessageIoTSDK,支持简单快速接入飞书消息提醒,方便接入告警服务(模拟西游记经典对白)

热门文章

  1. 网线专业测试软件,网线测试仪怎么用_网线测试仪的使用方法图解
  2. 无关风月怎谈价格:个性化直播源码打造多功能一对一交友、直播程序功能
  3. 湖南大学的计算机网络,林亚平-湖大信息科学与工程学院
  4. 免费开题报告|基于SpringBoot+Vue的校内跑腿平台
  5. 【修真院java小课堂】clean,install,package,deploy分别代表什么含义?
  6. 腾讯地图获取当前定位的经纬度、地址的详细名称和地图上的显示
  7. Python 正则表达式详解(re 库)
  8. IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)2017版
  9. word合并邮件无法发送html,Word邮件合并批量发送带附件的邮件
  10. 一般柱子与柱子的距离_砖混结构柱子间距多少合适?分分钟了解透彻