c++ swap函数头文件_C++函数模板(泛型编程)
模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。
模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。
每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 vector 或 vector 。
您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。
模板的引入
之前我们知道的交换两个变量的方法有宏定义、函数,这两种方式都能实现两个变量的交换,但是各有各的优缺点
宏定义:#define SWAP(a,b) {a=b-a;b=b-a;a=a+b;}
- 优点:代码复用,适合所有的类型
- 缺点:缺少类型检查,宏在预处理阶段就被替换掉,编译器并不知道宏的存在
函数:
- 优点:真正的函数调用,编译器对类型进行检查
- 缺点:类型不同需要重复定义函数,代码无法复用
上边两种方式都各有利弊,但是在C++中,存在泛型编程的概念:即不考虑具体数据类型的编程方式(如下)
如何定义函数模板
C++中的泛型编程有函数模板与类模板,这章我们先来了解函数模板
函数模板是一种特殊的函数,可以使用不同的类型进行调用,对于功能相同的函数,不需要重复编写代码,并且函数模板与普通函数看起来很类似,区别就是类型可以被参数化
函数模板通过template与typename(或者class)两个关键字来定义,如下
上边就定义了一个变量交换的函数模板,在使用函数模板时有两种方式
- 自动类型推到调用 Swap(a, b)
- 具体类型显示调用 Swap(a, b)
下边以代码来体验一下函数模板:
#includeusing namespace std;template <class T>void Swap(T& a, T& b){ T tmp = a; a = b; b = tmp;}void main(){ int a = 10; int b = 20; Swap(a, b); //自动推到调用 //Swap(a, b);//显示指定调用 cout <"a = " <" b = " <endl; float c = 12.3; float d = 23.4; //Swap(c, d); //自动推到调用 Swap<float>(c, d); //显示指定调用 cout << "c = " << c << " d = " << d << endl; system("pause");}
可以看到,我们使用函数模板,根据具体类型的参数化,就能适用于不同类型的变量交换,达到了代码复用的效果。
下边来深入理解下函数模板:
- 对于函数模板中使用的类型不同,编译器会产生不同的函数
- 编译器会对函数模板进行两次编译
- 第一次是对函数模板本身进行编译,包括语法检查等
- 第二次是对参数替换后的代码进行编译,这就相当于编译普通函数一样,进行类型规则检查等。
需要注意的是
- 函数模板是不允许隐式类型转换的,调用时类型必须严格匹配
传入不同类型会提示错误。
定义多个类型参数
函数模板还可以定义任意多个不同的类型参数,但是对于多参数函数模板:
- 编译器是无法自动推导返回值类型的
- 可以从左向右部分指定类型参数
#include using namespace std;//class typename都可以使用template <class T1, class T2, typename T3>T1 add(T2 a, T3 b){ T1 ret; ret = static_cast(a + b); return ret;}void main(){ int c = 12; float d = 23.4; //cout << add(c, d) << endl; //error,无法自动推导函数返回值 cout << add<float>(c, d) << endl; //返回值在第一个类型参数中指定 cout << add<int, int, float>(c, d) << endl; system("pause");}
在上边的代码中,我们定义了多类型参数的函数模板,调用时需要注意的是函数返回值需要在第一个参数类型中显示指定,后边的类型可自动推导或显示指定。
函数模板也可以重载
函数模板跟普通函数一样,也可以被重载
- C++编译器优先考虑普通函数
- 如果函数模板可以产生一个更好的匹配,那么就选择函数模板
- 也可以通过空模板实参列表<>限定编译器只匹配函数模板
#include using namespace std;template void fun(T a){ cout << "void fun(T1 a)" << endl;}template void fun(T1 a, T2 b){ cout << "void fun(T1 a, T2 b)" << endl;}void fun(int a, float b){ cout << "void fun(int a, float b)" << endl;}void main(){ int a = 0; float b = 0.0; fun(a); fun(a, b); //普通函数void fun(int a, float b)已经能完美匹配,于是调用普通函数 fun(b, a); //这个调用,函数模板有更好的匹配,于是调用函数模板 fun<>(a, b); //限定只使用函数模板 system("pause");}
从输出可以得到,编译器会优先去调用普通函数,但是当函数模板有更好的匹配时或使用限定符<>时,编译器就会去匹配函数模板。
总结
- 函数模板是泛型编程在C++中的应用方式之一
- 函数模板能够根据实参对参数类型进行推导
- 函数模板支持显示的指定参数类型
- 函数模板是C++中重要的代码复用方式
- 函数模板通过具体类型产生不同的函数
- 函数模板可以定义任意多个不同的类型参数
- 函数模板中的返回值类型必须显示指定
- 函数模板可以像普通函数一样重载
公众号ID:C语言Plus扫码关注最新动态
c++ swap函数头文件_C++函数模板(泛型编程)相关推荐
- strstr函数头文件_C语言(函数)学习之strstr strcasestr
一.strstr函数使用 [1] 函数原型 char *strstr(const char *haystack, const char *needle); [2] 头文件 #include [3] 函 ...
- strstr函数头文件_strstr函数
函数名: strstr 功 能: 在串中查找指定字符串的第一次出现 用 法: char *strstr(char *str1, char *str2); 程序例: #include #include ...
- c++ cout头文件_C/C++知识分享:C++常用内置函数你会几个,使用过几次呢?
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:Regina520 在 C++ 中,除了可以创建各种函数,还包含了各 ...
- C语言再学习 -- 常用头文件和函数(转)
参看:C/C++常用头文件及函数汇总 linux常用头文件如下: POSIX标准定义的头文件 <dirent.h> 目录项 <fcntl.h> 文 ...
- listlength函数头文件_酷町问答 - 我们编程时,通常要用到哪些头文件,包含什么函数...
1.常用数学函数 头文件 #include 或者 #include 函数原型 功能 返回值 int abs(int x) 求整数x的绝对值 绝对值 double acos(double x) 计算a ...
- VSCODE编译头文件时函数没有定义的解决方案(VSCODE手动链接C文件方法)
VSCODE编译头文件时函数没有定义的解决方案(VSCODE手动链接C文件方法) 参考文章: (1)VSCODE编译头文件时函数没有定义的解决方案(VSCODE手动链接C文件方法) (2)https: ...
- 【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )
文章目录 I . FFMPEG 交叉编译后的函数库及头文件 II . FFMPEG 静态库打包动态库 ( 仅做参考 ) III . 创建 Android Studio 工程 IV . FFMPEG 头 ...
- rt-thread 学习(二)外部中断 添加头文件 延时函数
rt-thread 学习(二)外部中断 添加头文件 延时函数 设置按键外部中断 开启硬件定时器 初始化配置部分 延时函数 添加头文件 设置按键外部中断 #include <rtthread.h& ...
- c语言bzero函数头文件,嵌入q式c语言-文件操用.doc
嵌入q式c语言-文件操用 广东科学技术职业学院 广州学院 <嵌入式C语言程式设计> 实 验 报 告 专业:计算机应用班级:09计应成绩评定:学号:18姓名:申赟教师签名:谭雄乐实验1题目: ...
最新文章
- Python游戏开发,pygame模块,Python实现愤怒的小鸟【附带源码】
- HTML5中volume样式自定义,html5中关于volume属性的使用详解
- 自顶向下彻底理解 Java 中的 volatile 关键字
- mysql中文坑爹的东西
- Android网络视频播放器DEMO
- 微商分销代理新零售商城源码
- 不只是地图应用 带你走进GIS的新世界
- Android茶叶进销存源码分享
- 基于python的三维射线追踪库-ttcrpy详解(3)
- html将英文日期格式转化为中文日期格式,excel中文日期与英文日期的转换
- 如何将live stream发布到Youtube
- 方舟服务器占用多少内存,方舟生存进化占用多少内存
- 【C++ 程序】 TVJ Complex Calculator (v 2.1) 复数计算器
- 软件工程作业--网上书店
- linux下的go富集分析,GO富集分析示例【华为云技术分享】
- Milk Measurement
- RSA加密算法加密与解密过程解析
- Arduino控制TM1637共阳四位数码管
- 服务器系统server2008 qq,WindowsServer2008R2服务器系统安装教程
- discuz mysql 类_Discuz论坛中的的MySQL类解析
热门文章
- 验证码识别技术(1) - 边缘检测
- IT市场10大技术伟人 Linux之父居首(转)
- React Native Android启动白屏的一种解决方案下
- 异常处理中throws和throw的区别?
- 表单界面的兼容PC手机端解决方案
- win10更新后程序路径盘符变成*星号解决方法
- Jenkins报错‘Gradle build daemon disappeared unexpectedly‘的问题解决
- 关于系统弹出错误:429 , ActiveX 部件不能创建对象 的解决方法
- 返回,返回无,根本没有返回?
- 如何分割字符串以便可以访问项目x?