【C++】模版初阶:函数模板、类模板
文章目录
- 一、为什么要使用模板
- 二、什么是函数模板
- 1、函数模板
- (1)概念
- (2)格式
- (3)原理
- (4)函数模板的实例化
- (5)模板参数的匹配原则
- 2、类模板
- (1)定义格式
- (2)实例化
- (3)用法
- 三、谢谢观看!
一、为什么要使用模板
举一个我们常用的交换函数来说:若我们用现学的知识实现一个通用的交换函数,即完成int、double、char等不同类型的交换,我们要如何写呢?
void Swap(int& left, int& right)
{int temp = left;left = right;right = temp;
}
void Swap(double& left, double& right)
{double temp = left;left = right;right = temp;
}
void Swap(char& left, char& right)
{char temp = left;left = right;right = temp;
}
......
类似于上面的方法,用函数重载来写,但缺点很明显:
- 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增
加对应的函数- 代码的可维护性比较低,一个出错可能所有的重载均出错
那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?这就要来介绍模版了。
模板分为函数模板和类模板。
模板类似于活字印刷,写一个模板,要哪种类型的就给它哪种类型。
二、什么是函数模板
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。
1、函数模板
(1)概念
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
(2)格式
template<typename T1, typename T2,…,typename Tn>
返回值类型 函数名(参数列表){}
//模版类型
//template<class T>
template<typename T> //一个模板参数
void Swap( T& left, T& right)
{T temp = left;left = right;right = temp;
}
注:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)
C++库里面有swap,包头文件 < utility >就可以直接用swap函数了。
(3)原理
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。
所以模板就是将本来应该我们做的重复的事情交给了编译器,让编译器替我们干活!
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。
比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。
(4)函数模板的实例化
用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。
- 隐式实例化:让编译器根据实参推演模板参数的实际类型
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
int main()
{int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add(a1, a2);//a1 a2均为int类型Add(d1, d2);//d1 d2均为double类型。隐式实例化
}
仍以上段代码为例,如果我传的参数类型不同呢,即 Add(a1, d1);
这时,有三种改法:
第一种(强制类型转换)
int main()
{int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add(a1,(int)d1); //强制类型转换将d1强转为int类型。
}
第二种(设置两个模板参数)
template<class T1, class T2>
T1 Add(const T1& left, const T2& right)
{return left + right;
}
int main()
{int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add(a1, d1);//这时候就可以随便传参了
}
第三种(显式实例化)
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
int main()
{int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add<int>(a1, d1);//指定模板类型为int类型,若类型不匹配,编译器会进行隐式类型转换。
}
- 显式实例化:在函数名后的<>中指定模板参数的实际类型。
如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。
(5)模板参数的匹配原则
我们先来假设一个场景,当一个程序中存在两个同名元素,其中一个是函数(有具体参数类型),一个是函数模板(无有具体参数类型),这时,调用函数,编译器会优先执行哪一个呢?例一下代码:
#include<iostream>
using namespace std;// 专门处理int的加法函数
int Add(int left, int right)
{return (left + right) * 10;
}// 通用加法函数
template<class T>
T Add(T left, T right)
{return left + right;
}int main()
{cout << Add(1, 2) << endl;return 0;
}
揭晓答案:
- 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数。
- 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板。
- 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
2、类模板
(1)定义格式
//同样,格式中的class也可以用typename
template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};
(2)实例化
类模板都是显示实例化的!!!编译器不会进行推导
类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。
(3)用法
以栈为例,我们之前在栈中想要更改存放的数据类型,直接用typedef进行替换,但若在一个程序中开两个类型不同的栈就不能用。现在,有了类模板,我们就可以开不同类型的栈了。
例:
template<typename T>
class Stack
{
public:Stack(int n = 4):_array(new T[n]),_size(0),_capacity(n){}~Stack(){delete[] _array;_array = nullptr;_size = _capacity = 0;}void Push(const T& x){//……}private:T* _array; //栈中存放的数据类型size_t _capacity;size_t _size;
};int main()
{Stack<int> s1;//栈中存放的数据为int类型Stack<double> s2;//栈中存放的数据为double 类型return 0;
}
三、谢谢观看!
相关文章:
【C++】模版初阶:函数模板、类模板
文章目录 一、为什么要使用模板二、什么是函数模板1、函数模板(1)概念(2)格式(3)原理(4)函数模板的实例化(5)模板参数的匹配原则 2、类模板(1&…...
Kotlin基础知识全面解析(下)
文章目录 第六章:集合与函数式编程6.1 集合概述6.2 集合操作6.3 序列 第七章:协程与异步编程7.1 协程基础7.2 挂起函数7.3 异步与等待7.4 协程上下文与调度器 第八章:Kotlin标准库8.1 作用域函数let函数run函数with函数apply函数also函数 8.2…...
NVIDIA高级辅助驾驶安全报告解析
近期参加了NVIDIA高级辅助驾驶开发者实验室,读了NVIDIA的高级辅助驾驶安全报告白皮书,里面涉及了不少有意思的内容,大致分享下英伟达在高级辅助驾驶领域的安全性上的工作。 最令人印象深刻的是NVIDIA提出的"四大支柱"架构&#x…...
HarmonyOS:一多能力介绍:一次开发,多端部署
概述 如果一个应用需要在多个设备上提供同样的内容,则需要适配不同的屏幕尺寸和硬件,开发成本较高。HarmonyOS 系统面向多终端提供了“一次开发,多端部署”(后文中简称为“一多”)的能力,可以基于一种设计…...
位运算题目:解码异或后的排列
文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题:解码异或后的排列 出处:1734. 解码异或后的排列 难度 6 级 题目描述 要求 有一个整数数组 perm \texttt{perm} perm,是前…...
elasticsearch查询中的特殊字符影响分析
大家先看一个执行的dsl 查询sql,大致的意思是排除某些分类下的商品 GET /productinfos/_search {"from": 0,"query": {"bool": {"must": [{"exists": {"field": "minprice"}},{"bool": {&qu…...
Django创建的应用目录详细解释以及如何操作数据库自动创建表
创建好Django项目后 如果要创建 python manage.py startapp 模块名模块 使用 我创建一个system模块后是 注意:urls是我自己建的文件 1.migrations目录 存放数据库的迁移文件,当models.py中模型定义发生变化时,通过迁移操作能同步数据库结构变化 __init__ 使该目录…...
Visual Studio Code 使用tab键往左和往右缩进内容
使用VSCode写东西,经常遇到多行内容同时缩进的情况,今天写文档的时候就碰到,记录下来: 往右缩进 选中多行内容,点tab键,会整体往右缩进: 往左缩进 选中多行内容,按shifttab&am…...
数据结构算法复杂度介绍
数据结构:互相之间存在一种或者多种特定元素的集合,在逻辑上分为线性结构,散列结构,、树形结构、图形结构等。 算法:求解具体问题的步骤描述,代码上表现出来是解决特定问题的一组有限的指令序列。简单来说…...
SiamMask中的分类分支、回归分支与Mask分支,有何本质差异?
SiamMask中的分类分支、回归分支与Mask分支,有何本质差异? 一、引言二、分支定位与任务目标三、网络结构与感受野设计3.1 分类分支(Classification Head)3.2 回归分支(Regression Head)3.3 Mask分支&#x…...
使用 Typora + PicGo + Gitee/GitHub 构建 Markdown 图床技术方案
使用 Typora PicGo Gitee/GitHub 构建 Markdown 图床技术方案 AuthorDateVersionNoteTao Wang2025-04-24V1.0Release the document. 文章目录 使用 Typora PicGo Gitee/GitHub 构建 Markdown 图床技术方案前言核心概念解析图床技术原理 环境搭建基础工具清单软件安装流程 …...
问道数码兽 怀旧剧情回合手游源码搭建教程(反查重优化版)
本文将对"问道数码兽"这一经典卡通风格回合制手游的服务端部署与客户端调整流程进行详细拆解,适用于具备基础 Windows 运维和手游源码调试经验的开发者参考使用。教程以实战为导向,基于原始说明内容重构优化,具备较高的内容查重避重…...
Electron Forge【实战】百度智能云千帆大模型 —— AI聊天
1. 获取 Access Key 与 Secret Key 登录百度智能云 https://login.bce.baidu.com/ 2. 安装node.js sdk npm install baiducloud/qianfan3. src/main.ts import { setupIPC } from "./ipc";在 const mainWindow 之后 setupIPC(mainWindow);4. src/ipc.ts import { ipc…...
机器人操作中的生成式 AI:综述(下)
25年3月来自香港大学、香港理工、香港科大、浙大和清华大学的论文“Generative Artificial Intelligence in Robotic Manipulation: A Survey”。 本综述全面回顾机器人操作领域生成学习模型的最新进展,并探讨该领域的关键挑战。机器人操作面临着关键瓶颈ÿ…...
把一个 PyTorch 的图像张量转换成 NumPy 格式,并按照正确的维度顺序显示出来
示例代码: plt.imshow(np.transpose(tensor_denorm.numpy(), (1, 2, 0)))它的作用是:把一个 PyTorch 的图像张量转换成 NumPy 格式,并按照正确的维度顺序显示出来。 🚀 一步步解释: ✅ tensor_denorm 这是一个形状为…...
windows上的RagFlow+ollama知识库本地部署
一、 docker的安装与部署 1. 下载Docker Desktop 访问Docker官网并下载适用于Windows的Docker Desktop安装程序。 RagFlow对docker的要求: Docker ≥ 24.0.0 & Docker Compose ≥ v2.26. docker 下载地址: https://www.docker.com/ Get Docker | D…...
【docker】 pull FROM build
镜像拉取失败 token问题 DeadlineExceeded: failed to fetch anonymous token Get "https://auth.docker.io/token?...": dial tcp 157.240.20.8:443: i/o timeout1. 检查网络连通性 如果 curl 命令卡住或超时,说明网络到 Docker Hub 存在问题。 ping regt-1.doc…...
【数据分析实战】使用 Matplotlib 绘制玫瑰图
🌹 1、简述 玫瑰图,又称极坐标柱状图(Polar Bar Chart),是一种特殊的条形图,适用于展示方向型数据,例如: 风向频率图(Wind Rose)每月、每日不同类别统计圆形时间序列展示(如12个月销售量分布)在本篇博客中,我们将使用 matplotlib 画出玫瑰图,包括基本玫瑰图、多…...
第十四届蓝桥杯省B.砍树
第十四届蓝桥杯省B.砍树 题目 题目解析及思路 考虑一对无序数对的点 x和 y,如果我们砍掉某条边可以让这两个点不连通,那么这条边一定是从 x到 y 路径上的一点,我们可以让从 x到 y 路径的边权值都加1。这个操作我们可以使用树上差分。 对于 …...
windows安装Mysql
一、删除已安装的MySQL服务 1、查找以前是否装有mysql sc query mysql 无结果,说明未安装过mysql或者已经卸载mysql服务,接下来直接安装mysql即可,否则需要删除之前安装的mysql 2、删除mysql 以管理员模式打开命令运行行,运行下…...
Axure大屏可视化模板:多领域数据决策的新引擎
在数据驱动决策的时代,Axure大屏可视化模板凭借交互性与可定制性,成为农业、园区管理、智慧城市、企业及医疗领域的创新工具,助力高效数据展示与智能决策。 核心应用场景 1. 农业精细化:实时监控土壤湿度、作物生长曲线&#x…...
【产品经理从0到1】原型及Axure介绍
原型分类 原型的三种分类: 草图原型:⼿绘稿,制作⽅便,修改不⽅便;低保真原型:简单交互,⽆设计图; 最好的原型是⿊⽩灰的;⾼保真原型:复杂交互,有…...
【激光雷达3D(7)】CenterPoint两阶段细化仅使用BEV特征;PV-RCNN两阶段细化使用体素特征;M3DETRTransformer统一多表征特征
文章目录 1. CenterPoint的两阶段细化模块仅使用鸟瞰视角(BEV)特征2 PV-RCNN 两阶段3 M3DETR(假设为类似DETR的3D检测器) 1. CenterPoint的两阶段细化模块仅使用鸟瞰视角(BEV)特征 CenterPoint的两阶段细化…...
C# 音频分离(MP3伴奏)
编程语言:C# 库:NAudio NAudio 是一个开源的 .NET 音频处理库,它为开发者提供了丰富的功能,能在 Windows 平台上方便地进行音频的录制、播放、处理等操作。以下是关于 NAudio 库的详细介绍: 主要特性 多格式支持&am…...
JavaScript性能优化实战(4):异步编程与主线程优化
JavaScript单线程模型与事件循环深入理解 JavaScript作为一种单线程语言,其执行模型与传统多线程编程语言有着根本性的差异。这种单线程特性既是JavaScript的局限,也是其简洁性的来源。深入理解JavaScript的单线程模型和事件循环机制,对于编写高性能的异步代码至关重要。 …...
Control Center安卓版:自定义控制中心,提升手机操作体验
在使用智能手机的过程中,许多用户希望能够更加便捷地访问常用功能和工具,提升操作效率。今天,我们要介绍的 Control Center安卓版,就是这样一款功能强大的手机控制软件。它不仅提供了简便的操作方法,还允许用户自定义操…...
Web3.0的认知补充(去中心化)
涉及开发技术: Vue Web3.js Solidity 基本认知 Web3.0含义: 新一代互联网思想:去中心化及用户为中心的互联网 数据:可读可写可授权 核心技术:区块链、NFT 应用:互联网上应用 NFT &…...
在Vue3中,如何在父组件中使用v-model与子组件进行双向绑定?
在 Vue 3 里,借助 v-model 可以轻松实现父组件与子组件的双向绑定。以下为你详细介绍实现步骤与示例代码。 实现原理 v-model 在 Vue 3 里是一种语法糖,它本质上是 :modelValue 和 update:modelValue 的组合。父组件借助 :modelValue 向子组件传递数据…...
沁恒MounRiver Studio无法printf浮点数
最近在使用沁恒MounRiver Studio进行CH32V307进行开发,但是遇到了已经成功获得浮点数,但是无法printf输出浮点数 如下图所示: 经过查找资料后,发现沁恒MounRiver Studio如果要printf输出浮点数需要打开Use float with nano print…...
初识Redis · 主从复制(下)
目录 前言: 数据同步 全量复制 部分复制 实时复制 前言: 前文我们已经介绍过了主从复制的基本概念,即分布式系统中存在多个Redis节点,一个是充当为主节点,其他的为从节点,并且从节点也是可以成为主节…...
BDO分厂开展地沟“大清肠”工作
BDO分厂装置区内的地沟主要回收生产过程中产生的污水、日常雨水,日积月累地沟内堆积了一层淤泥和杂物。厚厚的淤泥气味不仅影响员工健康,而且造成排水系统不畅通,存在安全隐患。分厂借助此次待产停车的有利时机对沉积已久的淤泥进行一次彻底“…...
程序和进程的详细对比
💡 一、程序(Program) ✅ 定义: 程序是一组指令的集合,通常是一个 可执行文件(如 .exe、.out),它是静态的、保存在磁盘上的一段代码,还没有被执行。 ✅ 特点ÿ…...
Flink介绍——实时计算核心论文之Flink论文
引入 通过前面的文章,我们梳理了大数据流计算的核心发展脉络: S4论文详解S4论文总结Storm论文详解Storm论文总结Kafka论文详解Kafka论文总结MillWheel论文详解MillWheel论文总结Dataflow论文详解Dataflow论文总结 而我们专栏的主角Flink正是站在前人的…...
【C++指南】位运算知识详解
. 💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《C指南》 期待您的关注 文章目录 引言一、位运算符概述1. 按位与(&)2. 按位或(|&#…...
网络开发基础(游戏)之 数据交换格式
数据交换格式是不同系统、应用程序或组件之间传输和共享数据时使用的标准化数据表示方式。在网络通信中,数据交换格式的选择直接影响系统的性能、可维护性和扩展性。以下是常用的数据交换格式的介绍和选择建议。 Protobuf (Protocol Buffers)协议缓冲区 是 Googl…...
怎么配置一个kubectl客户端访问多个k8s集群
怎么配置一个kubectl客户端访问多个k8s集群 为什么有的客户端用token也访问不了k8s集群,因为有的是把~/.kube/config文件,改为了~/.kube/.config文件,文件设置成隐藏文件了。 按照kubectl的寻找配置的逻辑,kubectl找不到要访问集群…...
【MongoDB】卸载、安装低版本
卸载 MongoDB 的步骤因操作系统而异,以下是 Windows、macOS 和 Linux 的详细卸载方法: 1. Windows 卸载 MongoDB 方法 1:通过控制面板卸载 打开控制面板 Win R → 输入 appwiz.cpl → 回车 找到 MongoDB 在程序列表里找到 MongoDB Server …...
WGAN+U-Net架构实现图像修复
简介 简介:该论文提出了一种基于Wasserstein生成对抗网络(WGAN)的图像修复方法,使用U-Net生成器,通过对抗损失与内容损失联合训练,有效解决了传统方法对破损区域形状大小受限、修复痕迹明显的问题。在CelebA和LFW数据集上的实验表明,该方法修复效果优于现有技术,尤其对…...
vscode vue文件单行注释失效解决办法
打开设置,搜索 files.associations,添加项 *.vue html 点击确定即可...
机器学习(7)——K均值聚类
文章目录 1. K均值(K-means)聚类是什么算法?2. 核心思想2. 数学目标3. 算法步骤3.1. 选择K个初始质心:3.2.迭代优化3.3. 重复步骤2和步骤3: 4. 关键参数5. 优缺点6. 改进变种7. K值选择方法8. Python示例9. 应用场景10…...
LainChain技术解析:基于RAG架构的下一代语言模型增强框架
摘要 随着大语言模型(LLM)在自然语言处理领域的突破性进展,如何突破其知识时效性限制、提升事实准确性成为关键挑战。LainChain通过整合检索增强生成(RAG)技术,构建起动态知识接入框架,为LLM提供实时外部知识支持。本文从技术原理、架构设计、应用场景三个维度,深入解…...
Java 使用 RabbitMQ 消息处理(快速上手指南)
目录 一、前言二、RabbitMQ 简介三、开发环境搭建3.1 安装 RabbitMQ在 Ubuntu 上安装在 Windows 上安装使用 Docker 安装3.2 添加 Maven 依赖四、RabbitMQ 的核心概念BrokerVirtual hostConnectionChannelExchangeQueueProducerConsumer五、RabbitMQ 基本操作5.1 发送消息(生产…...
Java 2025 技术全景与实战指南:从新特性到架构革新
作为一名Java开发者,2025年的技术浪潮将带给我们前所未有的机遇与挑战。本文将带你深入探索Java生态的最新发展,从语言特性到架构革新,助你在技术洪流中把握先机! 🌟 Java 2025 新特性全景 1. 模式匹配的全面进化 (J…...
【hadoop】HBase shell 操作
1.创建course表 hbase(main):002:0> create course,cf 2.查看HBase所有表 hbase(main):003:0> list 3.查看course表结构 hbase(main):004:0> describe course 4.向course表插入数据 hbase(main):005:0> put course,001,cf:cname,hbase hbase(main):006:0> …...
rabbitmq死信队列处理
创建私信队列并绑定 # 死信交换机配置 以直连交换机为列 my:exchangeNormalName: exchange.normal.a #正常交换机queueNormalName: queue.normal.a #正常队列exchangeDlxName: exchange.dlx.a #死信交换机queueDlxName: queue.dlx.a #死信队列…...
基于事件驱动的云原生后端架构设计:从理念到落地
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:微服务之后,事件驱动正在成为新范式 随着业务复杂度的提升,传统同步式微服务调用模式逐渐暴露出瓶颈:服务间耦合度高、并发能力有限、出错链路复杂。而在互联网业务、金融交易、物联网等场景中…...
CentOS 7 磁盘阵列搭建与管理全攻略
CentOS 7 磁盘阵列搭建与管理全攻略 在数据存储需求日益增长的今天,磁盘阵列(RAID)凭借其卓越的性能、数据安全性和可靠性,成为企业级服务器和数据中心的核心存储解决方案。CentOS 7 作为一款稳定且功能强大的 Linux 操作系统&am…...
区块链技术:深入共识算法、智能合约与DApps的架构奥秘
引言:区块链的颠覆性潜力 在数字化浪潮席卷全球的今天,区块链技术以其独特的去中心化特性、不可篡改的数据记录和透明的交易机制,正在重塑我们对信任、价值交换和组织形式的理解。从比特币的诞生到以太坊的智能合约革命,再到如今…...
深度学习物理信息神经网络PINN+大模型辅助编程
1. 物理信息神经网络(PINN)的兴起 近年来,物理信息神经网络(Physics-Informed Neural Networks, PINN)成为计算科学与人工智能交叉领域的前沿方向。传统数值方法(如有限差分法、有限单元法)在高…...
vue element使用el-table时,切换tab,table表格列项发生错位问题
展示问题 问题描述:使用el-table的fixed"right"属性后,如果切换tab时,回出现最后一列错误的问题 官网提供解决方法:doLayout 需要注意的事项:我这里是通过组件使用的table组件,涉及多层组件封装…...