【C++】函数模板和类模板
目录
1.泛型编程
2.函数模板
2.1函数模板的定义格式
2.2函数模板的实例化
2.3函数模板参数的匹配原则
3.类模板
3.1类模板的定义格式
3.2类模板的实例化
3.3模板的分离编译
1.泛型编程
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段,模板是泛型编程的基础
为什么存在泛型编程:
我们之前实现过交换两个整型的函数,如下:

但是要实现交换两个浮点型数据时,swap函数就不可用了
我们需要再编写交换两个浮点型的swap函数

但是这样就造成了大量的代码重复,因为这两个swap函数只有参数的类型不同
解决方案:
1️⃣函数重载:
- 重载的函数仅仅是类型不同,代码复用率比较低,只要有新的类型出现时,仍需要用户自己增加对应的函数
- 代码的可维护性比较低,一个出错可能所有的重载出错
2️⃣泛型编程:
给编译器一个模板,让编译器根据不同的类型由该模板生成代码
2.函数模板
2.1函数模板的定义格式
函数模板:代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本
函数模板格式:
template<typename T1, typename T2, ..... , typename Tn>
返回值类型 函数名(参数列表){ }📖Note:
typename是用来定义模板参数的关键字,也可以使用class,但不能使用struct代替class

2.2函数模板的实例化
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。模板就是将本来应该我们做的重复的事情交给给了编译器

在编译器编译阶段,编译器需要根据传入实参类型来推演生成对应类型的函数以供调用。如上例中,当使用char类型使用函数模板时,编译器通过对实参类型的推演,将T确定为char类型,然后产生一份专门处理char类型的代码,对于int和float类型同理
用不同类型的参数使用函数模板称为函数模板的实例化。
函数模板的实例化分类:
- 隐式实例化:让编译器根据实参推演函数模板参数的实际类型
- 显式实例化:在函数名后的<>中指定模板参数的实际类型


如上图:Add(a1, b1)该语句编译不能通过,当编译器推演其实参类型时,首先通过实参a1将T推演为int,通过实参b1将T推演为double,但是模板参数列表中只要一个T,编译器无法确定此处T的具体类型,因此报错
📖Note:
- 在模板实例化时,编译器一般不会进行类型转换操作
解决方案:
- 用户自己强制转换:Add(a1,(int) b1)
- 使用显式实例化
- 模板参数定义类型


2.3函数模板参数的匹配原则
1️⃣一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数

2️⃣对于非模板函数和同名函数模板,如果其他条件都相同,在调用时会优先调用非模板函数,而不是从该模板实例化一个函数。如果模板可以产生一个具有更好匹配的函数,那么将选择模板

3️⃣模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
3.类模板
3.1类模板的定义格式
类模板格式:
template<class T1,class T2, ..... , class Tn>
class 类模板名{
//类内成员定义
}
//动态顺序表的类模板
template<class T>
class Vector
{
public://构造函数Vector(size_t capacity = 10):_pDate(new T[capacity]), _size(0), _capacity(10){}//析构函数:在类中声明,类外定义~Vector();//void PushBack(const T& data);//void PopBack();size_t Size(){return _size;}//运算符[]重载//定义成内联函数,提高效率inline T& operator[](size_t pos){assert(pos < _size);return _pDate[pos];}private:T* _pDate;size_t _size;size_t _capacity;
};
//类外定义成员函数:需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{if (_pDate){delete[] _pDate;}_size = _capacity = 0;
}
3.2类模板的实例化
类模板实例化和函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板的名字不是真正的类,而实例化的结果才是真正的类
int main()
{//Vector类名,Vector<int> s1才是类型Vector<int> s1;Vector<double> s2;return 0;
}
3.3模板的分离编译
模板不支持分离编译,会产生链接错误

解决方案:
🔷显式实例化
在定义的地方,指定是模板
🔷不分离定义到.h和.cpp中
把类模板定义到.h文件中(包括声明和定义),实例化后编译,就知道函数的地址,不需要链接去符号表中去找函数的地址
相关文章:
【C++】函数模板和类模板
目录 1.泛型编程 2.函数模板 2.1函数模板的定义格式 2.2函数模板的实例化 2.3函数模板参数的匹配原则 3.类模板 3.1类模板的定义格式 3.2类模板的实例化 3.3模板的分离编译 1.泛型编程 泛型编程:编写与类型无关的通用代码,是代码复用的一种手段…...
Echarts 配置项 series 中的 data 是多维度
文章目录 需求分析 需求 如下图数据格式所示,现要求按照该格式进行绘制折线图 分析 在绘制折线图时,通常我们的 series 中的 data 数据是这样的格式 option {title: {text: Stacked Area Chart},tooltip: {trigger: axis,axisPointer: {type: cross…...
快速了解Redis
Redis是什么? Redis是一个数据库,是一个跨平台的非关系型数据库,Redis完全开源,遵守BSD协议。它通过键值对(Key-Value)的形式存储数据。 与传统数据库不同的是 Redis 的数据是存在内存中的 ,也就是它是内存数据库&am…...
1.2_2 OSI参考模型
文章目录 1.2_2 OSI参考模型一、概述(一)ISO/OSI参考模型是怎么来的?(二)ISO/OSI参考模型(三)ISO/OSI参考模型解释通信过程 二、各层功能及协议(一)应用层(第…...
CVPR 2024 | Modular Blind Video Quality Assessment:模块化无参视频质量评估
无参视频质量评估 (Blind Video Quality Assessment,BVQA) 在评估和改善各种视频平台并服务用户的观看体验方面发挥着关键作用。当前基于深度学习的模型主要以下采样/局部块采样的形式分析视频内容,而忽视了实际空域分辨率和时域帧率对视频质量的影响&am…...
C++指针(五)完结篇
个人主页:PingdiGuo_guo 收录专栏:C干货专栏 前言 相关文章:C指针(一)、C指针(二)、C指针(三)、C指针(四)万字图文详解! 本篇博客是介…...
使用registry镜像创建私有仓库
通过安装Docker后,Docker官网提供的registry镜像简单搭建一套本地私有仓库 1.通过registry镜像 ,做端口映射,创建一个容器,通过容器内的一个目录来创建私有仓库 并且将容器内仓库与本地路径做挂载 [rootnode1 ~]# docker run -d…...
前端发展史与优秀编程语言
前端开发是互联网技术领域中的一个重要分支,负责构建用户直接交互的网页和应用程序界面。随着互联网的发展,前端技术经历了多个阶段的演变,从最初的简单静态页面到如今的复杂交互式应用,不断推动着用户体验的提升和网页功能的丰富…...
利用SQL Server 进行报表统计的关键SQL语句与函数
在数据库应用中,报表统计是一项至关重要的任务,它为企业提供了数据洞察和决策支持。SQL Server作为一种强大的关系型数据库管理系统,提供了丰富的SQL语句和函数,可用于高效地进行报表统计。本文将介绍一些常用的SQL语句和函数&…...
【目标检测】旋转目标检测COCO格式标注转DOTAv1格式
DOTAv1数据集格式: imagesource:imagesource gsd:gsd x1, y1, x2, y2, x3, y3, x4, y4, category, difficult x1, y1, x2, y2, x3, y3, x4, y4, category, difficult ... imagesource: 图片来源 gsd: 分辨率 x1, y1, x2, y2, x3, y3, x4, y4:四边形的四…...
数据结构与算法:链式二叉树
上一篇文章我们结束了二叉树的顺序存储,本届内容我们来到二叉树的链式存储! 链式二叉树 1.链式二叉树的遍历1.1二叉树的前序,中序,后序遍历1.2 三种遍历方法代码实现 2. 获取相关个数2.1获取节点个数2.2获取叶节点个数2.3 获取树的…...
SpringMVC中接收参数总结
目录 一、引子 二、注解解析 RequestParam 一、要求形参名请求参数名,或者是请求实体类时(已有实体类),可以不需要加该注解 二、请求参数名!参数名时,需要写该注解RequestParam,其中 三、一名多值的情…...
使用 SPL 高效实现 Flink SLS Connector 下推
作者:潘伟龙(豁朗) 背景 日志服务 SLS 是云原生观测与分析平台,为 Log、Metric、Trace 等数据提供大规模、低成本、实时的平台化服务,基于日志服务的便捷的数据接入能力,可以将系统日志、业务日志等接入 …...
《日期类》的模拟实现
目录 前言: 头文件类与函数的定义Date.h 实现函数的Date.cpp 测试Test.cpp 运行结果: 前言: 我们在前面的两章初步学习认识了《类与对象》的概念,接下来我们将实现一个日期类,是我们的知识储备更加牢固。 头文件…...
RocketMQ架构详解
文章目录 概述RocketMQ架构rocketmq的工作流程Broker 高可用集群刷盘策略 概述 RocketMQ一个纯java、分布式、队列模型的开源消息中间件,前身是MetaQ,是阿里研发的一个队列模型的消息中间件,后开源给apache基金会成为了apache的顶级开源项目…...
【AI视野·今日NLP 自然语言处理论文速览 第八十二期】Tue, 5 Mar 2024
AI视野今日CS.NLP 自然语言处理论文速览 Tue, 5 Mar 2024 (showing first 100 of 175 entries) Totally 100 papers 👉上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Key-Point-Driven Data Synthesis with its Enhancement on Mathematica…...
windows 两个服务器远程文件夹同步,支持文件新增文件同步、修改文件同步、删除文件同步,根据文件大小和时间戳判断文件是否修改 python脚本
在Python中实现Windows两个服务器之间的文件夹同步,包括文件新增、修改和删除的同步,可以使用paramiko库进行SSH连接以及SFTP传输,并结合文件大小和时间戳判断文件是否发生过变化。以下是包含删除文件同步逻辑的完整脚本示例: im…...
vite项目修改node_modules
问题详情 在使用某个依赖的时候遇到了bug,提交issue后不想一直等待到作者更新版本,所以寻求临时自己解决 问题解决 在node_modules里找到需要修改的依赖,修改想要修改的代码 修改后记得保存 然后在node_modules里找到.vite文件夹&#x…...
NLP神器Transformers入门简单概述
在这篇博客中,我们将深入探索 🤗 Transformers —— 一个为 PyTorch、TensorFlow 和 JAX 设计的先进机器学习库。🤗 Transformers 提供了易于使用的 API 和工具,使得下载和训练前沿的预训练模型变得轻而易举。利用预训练模型不仅能减少计算成本和碳足迹,还能节省从头训练…...
微信小程序-wxml语法
介绍 WXML(WeiXin Markup Language)是框架设计的一套标签语言,可以进行页面布局,声明事件,数据绑定,条件判断。 语法 数据绑定 <view> {{message}} </view>// page.js Page({data: { // 状态…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
