【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: { // 状态…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...

若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...

Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...