函数模板(初阶)
Hello,大家好,我们大家都知道,C++这个编程语言是由C语言继承而来的,因为是继承,所以我们的C++就要做出一些区分,要不然的话,就和C语言没有本质上的区别了,我们现在在社会中使用比较多的是C++而非是C语言,是因为这里我们C++的祖师爷在C语言的基础之上又设计了一个模板相关的内容,这个模板就受到了很多人的欢迎。
目录
1.前情提要
2.泛型编程
3.函数模板
3.1函数模板的概念
3.2函数模板的格式
3.3函数模板的原理
3.4函数模板的实例化
3.5模板参数的匹配原则
4.类模板
4.1类模板的格式
4.2类模板的实例化
1.前情提要
我们在C语言中经常会使用到一些相同的函数,就比如说Swap函数,我们在前面的C语言编程中就经常会使用到这个Swap函数来交换两个同类型的数据,我们要交换的数据的类型往往不止一种,我们要交换两个int类型的数据,double类型的数据等等,我们要为每一个类型的数据交换都要写一个Swap交换函数,这样就很费时间和空间,这些函数明明达到的效果都是一样的,但是却要写好多的一模一样的函数,很不爽,我们C++的祖师爷考虑到了这种情况,于是,就发明了模板这个东西来改变这种情况。
2.泛型编程
编写于类型无关的通用代码,是代码复用的一种手段,模板是泛型编程的一种基础。模板又分为函数模板和类模板。
3.函数模板
3.1函数模板的概念
函数模板代表了一个函数家族,该函数模板与类型无关,我们在使用时被参数化,根据实参类型从而产生函数的特定类型版本。
3.2函数模板的格式
template<class T>;
class T 就是参数列表的类型,编译器会根据类型来生成对应的函数,为了避免不必要的麻烦,因此这里建议参数列表中有几个形参,这里就写几个:
template<class T1,class T2......>
比如:在这里写一个Swap交换函数。
#include<iostream>
using namespace std;
template<typename T>
void Swap(T a1, T a2)
{T tmp=a1;a1 = a2;a2 = a1;
}
int main()
{int a = 11, b = 22;Swap(a, b);//这里我们调用Swap函数的时候,那个Swap模板中的T就被编译器自动识别为int,编译器会自动构造一个int类型的Swap函数。cout << a << " " << b << endl;//11 22double c = 1.1, d = 2.2;Swap(c, d);//当我们传double类型的数据过去的时候,这个Swap函数中的T就会被编译器自动识别为double,编译器会自动构造一个double类型的Swap交换函数。cout << c << " " << d << endl;//1.1 2.2char e = 'e', f = 'z';Swap(e, f);//当我们传char类型的数据过去的时候,这个Swap函数中的T就会被编译器识别为char,编译器会自动构造一个cahr类型的Swap交换函数。cout << e << " " << f << endl;//z ereturn 0;
}
注:typename是用来定义模板参数的关键字,我们这里再定义模板参数的时候,其实不仅仅能使用typename这一个关键字,我们还可以使用class这个关键字来代替上述代码中的typename关键字(class/typename这两个关键字的效果都是一样的,不管写谁都可以)。切记:这里不可以使用struct来代替class。
template<class T1,class T2>
3.3函数模板的原理
函数模板类似于就是一个蓝图一样,是编译器的使用方式产生特定具体类型函数的摸具。总结下来就是将原本应该有我们做的重复的事情交给了编译器去做。
template<typename T1,typename T2>
void swap(T1& x,T2& y)
{ }
在编译器的编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演并生成对应类型的函数,以供我们去使用,就比如说,当int类型处理上述的函数时,编译器会通过对实参类型的推演将T1,T2确定为是int类型,然后产生一份专门处理int类型的代码,任何类型均是如此。
3.4函数模板的实例化
用函数模板生成对应的函数这个过程成为是模板的实例化。
(1).隐式实例化:让编译器根据参数来推演模板参数的实际类型。
#include<istream>
using namespace std;
template<class T>//这里我们传过来的参数有几种类型,我们在这里就定义几个class/typename。
T add(T& a1, T& a2)
{return a1 + a2;
}
template<class T1,class T2>//这里我们传过来的参数有几种类型,我们在这里就定义几个class/typename。
void Add(T1& b1, T2& b2)
{int a = b1 + b2;
}
int main()
{int a1 = 1, a2 = 2;add(a1,a2);//编译器会自动根据出过去的实参(也就是a1和a2的类型)确定出T为int。double b1 = 1.1, b2 = 2.2;add(b1, b2);//编译器会自动根据出过去的实参(也就是b1和b2的类型)确定出T为double。Add(a1,b2);//编译器会自动根据出过去的实参(也就是a1和b2的类型)确定出T1为int类型,确定出T2为double类型。return 0;
}
注意:这里我们传过来的参数有几种类型,我们在这里就定义几个class/typename,如果我们传过去的参数类型有两种的话,但是我们定义的class/typename只有一种的话,那么,这样的话,编译器就无法分清这里定义的这个T是哪一个类型,就会出现编译报错的问题。
(2).显示实例化:在函数名后面的< >中指定模板参数的类型。
#include<istream>
using namespace std;
template<class T1,class T2>//这里我们传过来的参数有几种类型,我们在这里就定义几个class/typename。
void Add(T1& b1, T2& b2)
{ }
int main()
{int a1 = 1, a2 = 2;Add<int, int>(a1, a2);//T1是int类型,T2也是int类型。double b1 = 1.1, b2 = 2.2;Add<double, double>(b1, b2);//T1是double类型,T2也是double类型。Add<int, double>(a1, b2);//T1是int类型,T2是double类型。return 0;
}
注意:1>.这个显示实例化的知识我们必须要掌握,这个知识点我们在后面会大量使用。
2>.如果类型不匹配的话,那么编译器就会尝试着进行类型转换的操作,如果这个类型转换无法成功的话,编译器就会进行报错的操作。
3.5模板参数的匹配原则
(1).一个非模板函数可以和一个同名的函数木模板同时存在,而且该函数模板还可以被实例化为这个非模板函数。
(2).对于非模板函数和同名函数模板,如果其他的条件都相同的话,那在调用时会优先调用非模板函数,而不会从该模板中产生一个实例。如果模板可以产生一个具有更好匹配的函数,那么就会选择模板(换句话说,就是有现成的就用现成的,而不会自己创造一个)。
(3).模板函数不允许自动类型转换,但普遍函数却可以进行自动类型转换。
4.类模板
4.1类模板的格式
template<typename T1,typename T2>
class date//date是类模板名
{//类内成员变量
};
4.2类模板的实例化
类模板的实例化与函数模板的实例化不同,类模板实例化需要在类模板名字后面跟< >,然后将类型放在< >中即可,类模板的名字其实不是真正的类,而实例化的结果才是真正的类。
#include<iostream>
using namespace std;
template<typename T>
class date//定义了一个类类型的模板
{
public://我们在模板里面实现一个Add函数T Add(T& a1,T& a2){ }void Swap(T& b1, T& b2);
};
//接下来,我们来写一下Swap函数的定义,在写之前这里还必须要补充一个知识点,就是每一个模板的作用域它仅限于当前的这个类,除了这个类之后就不管了,因此,对于类外的函数来说,我们就必须还得重新再写一个模板。
template<typename T>
void date<T>::Swap(T& b1, T& b2)
{ }
int main()
{date<int> d;//类型名/类型:date<int> //(date<int>即是类型名,同时也是类型)return 0;
}
注意:类模板都是显示实例化。
今天我们关于初阶函数模板的知识就先讲到这里了,谢谢大家的支持,你们的支持就是我坚持的巨大动力。
相关文章:
函数模板(初阶)
Hello,大家好,我们大家都知道,C这个编程语言是由C语言继承而来的,因为是继承,所以我们的C就要做出一些区分,要不然的话,就和C语言没有本质上的区别了,我们现在在社会中使用比较多的是…...
中间件之RocketMQ
RocketMQ是一个开源的分布式消息队列系统,起源于阿里巴巴集团内部。最初,RocketMQ(前身为Metaq)被设计为满足阿里巴巴集团内部大规模分布式系统下的高吞吐量、低延迟和高可靠性的消息传递需求。随着其在阿里巴巴内部的广泛应用和不…...
linux第二课(docker的安装使用)
目录 一.关于docker (1)背景引入 (2)docker介绍 (3)功能 (4)Docker架构 二.docker的安装及相关的命令 (1)docker的安装 (2)docker的配置 (3)docker镜像命令 (4)容器命令 三.docker安装myaql 编辑 四.数据卷挂载 1.数据卷挂载引入 2.数据卷挂载图解 3.数据卷的安装…...
Java数据存储结构——二叉查找树
文章目录 22.1.2二叉查找树22.1.2.1 概述22.1.2.1二叉查找树添加节点22.1.2.2二叉查找树查找节点22.1.2.3 二叉树遍历22.1.2.4 二叉查找树的弊端 22.1.2二叉查找树 22.1.2.1 概述 二叉查找树,又称二叉排序树或者二叉搜索树 二叉查找树的特点: 每一个节点上最多有…...
JavaScript 事件处理
一、简介 事件:发生在HTML元素上的事情,可以是用户的行为,也可以是浏览器的行为,如 用户点击了某个HTML元素用户将鼠标移动到某个HTML元素上用户输入数据时光标离开页面加载完成 事件源:事件触发的源头…...
容器技术--Docker应用部署
应用部署 容器部署mysql 搜索并拉取镜像;基于镜像启动容器,注意端口映射、目录映射启动后即可连接# 搜索镜像 docker search mysql # 拉取镜像 docker pull mysql:5.7 # docker pull mysql 默认拉取最新的# 创建mysql容器, -p端口映射(宿主端口:容器端口) -e 环境变量,镜…...
医院管理|基于java的医院管理系统小程序(源码+数据库+文档)
医院管理系统小程序 目录 基于java的医院管理系统小程序 一、前言 二、系统设计 三、系统功能设计 医生信息管理 排班信息管理 科室信息管理 科室预约 病历信息 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取:…...
golang学习笔记21——golang协程管理及sync.WaitGroup的使用
推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...
C++初阶大全
目录 一.命名空间 1.命名空间定义 2.命名空间使用 二.C输入&输出 三.缺省参数 四. 函数重载 五.引用 1.常引用 2.传值、传引用效率比较 3.引用和指针的区别 4.引用和指针的不同点: 小知识点: 六.内联函数 七.auto关键字(C11) 1.auto的使用细则 八.基于范围…...
使用Redis实现用户关注博客的推模式
目录 一、思路 二、实现代码: 一、思路 发布者: 这里采用redis的zset结构,将键设置为被推送用户id,值设置为博客id,score设置为时间戳 推送之前先查到当前发布博客用户的粉丝有哪些,然后去循环挨个推送…...
python常用模块之time、datetime、randow(14)
文章目录 前言1、time模块1.1 导入模块1.2 使用方法1.2.1 时间戳1.2.2 程序休眠1.2.3 扩展:按某种格式显示当前时间1.2.4 结构化时间 2、datetime模块2.1 导入模块2.2 使用方法2.2.1 得到当前系统的时间2.2.2 拓展:编写一个时钟小程序 3、random模块3.1 …...
根据NVeloDocx Word模板引擎生成Word(六-结束)
前面几篇已经把E6开发平台配套的Word模版隐藏NVeloDocx的基础用法介绍了一遍,这些基础用法基本上可以完全覆盖实际业务的绝大部分需求。所以我们这一篇就介绍一些边边角角的内容,给本系列来一个首尾。 本篇的主要内容有: 1、汇总计算&#…...
Android架构组件:MVVM模式的实战应用与数据绑定技巧
目录 引言 一、MVVM模式概述 1.1 MVVM模式简介 1.2 MVVM模式的优势 二、MVVM模式的实现 2.1 项目环境配置 2.2 创建MVVM组件 2.2.1 创建数据模型 2.2.2 创建数据仓库 2.2.3 创建ViewModel 2.2.4 创建布局文件 2.2.5 创建RecyclerView适配器 2.3 在Activity中绑定V…...
调用系统的录音设备提示:line with format PCM_SIGNED 16000.0 Hz
javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 16000.0 Hz, 8 bit, mono, 1 bytes/frame, not supported. 打开 设置->隐私->麦克风->允许应用访问你的麦克风 与 16000Hz没关系 与 16000Hz没关系 与 16000Hz没关系...
android BLE 蓝牙的连接(二)
下面是基于实际的项目得到的具体步骤及核心代码 1、权限问题 先判断手机是否满足android4.3以上版本,再判断手机是否开启蓝牙 主要涉及蓝牙权限和位置权限,注意不同android版本之间权限申请的差异,以及android权限动态申请和静态申请的区别 …...
改编pikachu的打靶经历(题目不全)
前言 题目很少,只做了一些。正常版本的,完整的pikachu可参考下面这个师傅写的 https://www.cnblogs.com/henry666/p/16947270.html xss (get)反射xss 先尝试 1 这里有长度限制,而且,我改了长度…...
Linux进阶 修改文件所有者
修改文件所属组群——chgrp 修改文件所属组群很简单-chgrp命令,就是change group的缩写(我们可以利用这些来记忆命令) 语法:chgrp 组群 文件名/目录 举例: [root@redhat ~]# groupadd groupa[root@redhat ~]# groupadd groupb[root@redhat ~]# useradd -g groupa zgz[r…...
第312题|二重积分求旋转体体积(二)|武忠祥老师每日一题
解题思路:先画出图像,再利用旋转体体积计算公式进行解题。 1. 旋转体体积计算公式: 2.点到直线计算公式: 有了上面两条知识储备之后我们开始计算。 第一步:先计算出点到直线的距离: ymx,y-mx…...
redis基本数据结构-set
文章目录 1. set的基本介绍1.1. set底层结构之hash表的简单介绍1.2. 常用命令 2. 常见的业务场景2.1. 标签系统2.2. 社交网络好友关系 1. set的基本介绍 参考链接:https://mp.weixin.qq.com/s/srkd73bS2n3mjIADLVg72A redis 的 set 数据结构是一个无序的集合&#…...
Android 应用安装-提交阶段
经过前面准备、浏览、协调这些步骤,马上要进入提交阶段了。所谓提交,就是把这些安装应用的相关信息和状态都放到系统中。对于已安装普通应用,它其实分为两个步骤,先卸载旧包,再安装新包。当然,如果是新安装…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
goreplay
1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具,可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长,测试它所需的工作量也会呈指数级增长。GoRepl…...
Java多线程实现之Runnable接口深度解析
Java多线程实现之Runnable接口深度解析 一、Runnable接口概述1.1 接口定义1.2 与Thread类的关系1.3 使用Runnable接口的优势 二、Runnable接口的基本实现方式2.1 传统方式实现Runnable接口2.2 使用匿名内部类实现Runnable接口2.3 使用Lambda表达式实现Runnable接口 三、Runnabl…...
Python第七周作业
Python第七周作业 文章目录 Python第七周作业 1.使用open以只读模式打开文件data.txt,并逐行打印内容 2.使用pathlib模块获取当前脚本的绝对路径,并创建logs目录(若不存在) 3.递归遍历目录data,输出所有.csv文件的路径…...
Springboot 高校报修与互助平台小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,高校报修与互助平台小程序被用户普遍使用,为…...
2025-06-01-Hive 技术及应用介绍
Hive 技术及应用介绍 参考资料 Hive 技术原理Hive 架构及应用介绍Hive - 小海哥哥 de - 博客园https://cwiki.apache.org/confluence/display/Hive/Home(官方文档) Apache Hive 是基于 Hadoop 构建的数据仓库工具,它为海量结构化数据提供类 SQL 的查询能力…...
Jmeter(四) - 如何在jmeter中创建网络测试计划
1.简介 如何创建基本的 测试计划来测试网站。您将创建五个用户,这些用户将请求发送到JMeter网站上的两个页面。另外,您将告诉用户两次运行测试。 因此,请求总数为(5个用户)x(2个请求)xÿ…...
SAP学习笔记 - 开发24 - 前端Fiori开发 Filtering(过滤器),Sorting and Grouping(排序和分组)
上一章讲了SAP Fiori开发的表达式绑定,自定义格式化等内容。 SAP学习笔记 - 开发23 - 前端Fiori开发 Expression Binding(表达式绑定),Custom Formatters(自定义格式化)-CSDN博客 本章继续讲SAP Fiori开发…...
