c++----初识模板
大家好,这篇博客想与大家分享一些我们c++中比较好用的知识点。模板。首先咧,我们都知道模板嘛,就是以前人的经验总结出来的知识。方便我们使用。这里的模板也是一样的。当我们学习过后,对于一些在c中的自定义函数,我们在c++中使用就会很方便了。但是因为我们这里只是初识。因为我们现在学识尚浅,太过高深的话,就一点过载了,所以我们这里就暂时交给大家如何辨认和使用简单的模板。
泛型模板
首先我们可以从我们的标题看到我们这一小节讲的是广泛的模板,就是使用的范围相对较广,但是只是较广并不是通用。我们这里就以我们以前在c中常使用的一个自定义函数swap来说,但其实我们在c中就说过,我们学习了c++就不需要再自己写了,也不需要写头文件,因为我们c++中swap很有可能会被间接包含所以我们通常是直接使用,这里我们为了方便教学就以这个为例。
大家都知道,我们平常的swap是确定了参数类型的,不能不同参数进行交换,就像我们下面的图片:
在我们c的时候为了应对不同的参数类型所以我们需要写多个参数版本。使用函数重载虽然可以实现,但是有一下几个不好的地方:
1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数
函数模板
对于我们的函数模板,它代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。已就是说。我们的c++模板不会受到参数类型的限制,只要我们写的参数个数正确就可以了。虽然我这里很简单说,只需要确定参数个数就可以了。但其实也真的很简单。
那么我们就来看看函数的模板是如何书写的。首先我们要先写一个:template<typename T1, typename T2,......,typename Tn> 。大体是这样的但是个数就是自己确定。是不是很简单啊。那么我们来写一个swap模板,并且看看如何使用的: 上面的图片,大家可以看到在使用模板前,我们先写了一个声明。然后写的我们模板。这里大家是否有留意到我们声明的时候只写了一个参数类型啊,就是我们这里template<typename T>中只有一个参数。这就表明了我们这里的模板参数类型只能有一种参数类型。
我想大家看了上面的那句话应该会想到一个疑问吧,这就是啥意思啊。上面写了一个参数,就代表只有一种参数类型了。那是不是我上面多写几个,那么我就可以在模板中使用多种参数类型了呀。但确实是这样的,我们可以在声明的时候多些几种,那么模板就可以多使用几种,那我们来看看例子:
这里我们是没有报错的,这是因为我们在上面写了两个声明的类型,所以我们在模板中可以使用两种参数变量,虽然结果可能不尽人意但是我们的却还是确定了一点。我们如果在前面写多个参数那么下面的模板就可以使用多种参数类型。
注:括号里面的声明是只能写typename还可以写成clsaa,但是大家不要多想以为class可以写,那么struct也可以写。这就错了。表明参数类型能个数的就只有这两种表达。没有其他的了
函数模板的原理,对于我们学习的人来说,主打一个刨根问底。那么我们对于这个函数模板多多少少也是需要了解的。但其实大家如果看到这里了,就应该对函数模板的原理也差不多了吧。毕竟我们的标题就写的很清楚了啊。模板嘛。函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。我感觉有点像一个没有灵魂的人,只要有灵魂进入这幅躯体,那么这幅躯体就可以凭借这个灵魂带来的思想来完成自己的心愿。就像可以被人随意控制的木偶一样。大家可以看一下下面的图片: 这里就有点像我上面写的那个灵魂一样。只要想用就进入这幅空壳,凭借这幅躯体就可以做出其他的事情。但如果稍微官方一点的话就是:在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。这个大家可以复杂理解,也可以简单思考,反正我觉得稍微知道是个啥意思就可以了,如果深入太多的话,就可能有点吃不消了。
函数模板的实例化:大家可能看到这个小标题会有点懵。啊。实例化,什么个意思怎么会用在这里啊。大家别急。用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。这里我们知道了示例化有两种。一个是显示一个是隐式。那么我们就来先看看显示实例化:
我们这里的Add只写了一种参数个数,如果按我们前面说的话,不是只能有一种参数类型吗?这里怎么有两种啊。但大家应该也看到了,在我们调用的前面写了一个<int>。这就好比我们在c中写过的强制类型转换。只是我们写的这里是将这两个全都转换成int,int转换为int不变嘛,但是我double可以转换为it强制类型转换,当然也可以这样写:
反正如果我们写的参数个数类型只写了一个的话,我们可以将我们不同的参数类型进行转换,然后使用。还有对于隐式实例化的话就是比较简单的,其实就是我们普通的使用方法也是使用转换,就是我们相同的参数类型:
这就是我们说的隐式类实例化,就是我们平常的使用方法,但是对于我们如果想用两种不同的参数类型,并且我们的参数类型个数只有一个的话,就只能强转或者我们刚刚的显示实例化。

这里我是简单的用f11调试给大家看的,虽然可能大家会怀疑,但确实是这样,如果当一个非模板函数与模板函数同时调用的话,会先调用非模板函数,大家知道就可以了。模板函数不允许自动类型转换,但普通函数可以进行自动类型转换。
类模板
大家也看到了上面我们所有的文章都是依照函数来写的,但是我们c++呢肯定不只有函数,我们前面学的最多的就是类了,我们那也是有模板的。其实对于类的模板格式与我们的函数模板格式相差无几。区别就是我们类的写法,我们自定义函数的写法是不一样的。那么我们看一下类模板的定义格式是什么样的?
类模板的定义格式:
template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};
我们前面说过类模板的第一个是与我们的函数模板格式差不多,只是融汇了自己各自的特点。也许大家会想类模板有什么作用呢?
- 一些类主要用于存储和组织数据元素
- 类中数据组织的方式和数据元素的具体类型无关
- 如:数组类,链表类,Stack类,Queue类,等
C++中将模板的思想应用于类,使得类的实现不关注数据元素的具体类型,而只关注类所需要实现的功能。
实现类模板:
- 以相同的方式处理不同的类型
- 在类声明前使用template进行标识
- < typename T >用于说明类中使用的泛指类型T
这里我们是以我们C中使用过的扩容。大家可能很难看出来,但其实我们不看这个,我们主要是看我们的模板是如何使用的。后面大家加油以此为蓝本来写,也许大家会问啊,关于模板函数我们知道的少怎么分析这个类模板函数列:
1. 与函数模板不同,只能显示指定具体类型,无法自动推导。
2. 声明的泛指类型T 可以出现在类模板的任意地方
3. 编译器对类模板的处理方式和函数模板相同
a) 从类模板通过具体类型产生不同的类
b) 在声明的地方对类模板代码本身进行编译
c) 在使用的地方对参数替换后的代码进行编译
大家可以多理解上面分析。并且大家需要知道的一个不能忘的点就是我们类模板的头文件与源文件不能分开。具体是什么原因。在下暂时还不知道。但是我尝试过分开确实会报错的,所以大家现在知道不能分开就可以了。
// Stack是类名,Stack<int>才是类型
Stack<int> st1; // int
Stack<double> st2; // double
总结
好的,上面这些就是本篇博客想与大家分享的模板的一些相关的基础知识,我知道可能大家会很多的不了解,尤其是类模板的。相较于函数模板的话,类模板确实要有更多的知识点,但是大家不要害怕,我们可以多稍微多理解几遍,看几遍就可以了解的更多了。模板嘛,毕竟是我们c++中最好用的一个东西啊,因为相较于c中它没有我们c++有就更好用了。好,鄙人在这里祝各位前程似锦!!!
相关文章:

c++----初识模板
大家好,这篇博客想与大家分享一些我们c中比较好用的知识点。模板。首先咧,我们都知道模板嘛,就是以前人的经验总结出来的知识。方便我们使用。这里的模板也是一样的。当我们学习过后,对于一些在c中的自定义函数,我们在…...

SpringBoot3热部署
引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional> </dependency> 默认就是,无需配置 可以了…...

J. 二进制与、平方和
https://codeforces.com/gym/104095/problem/J 分析操作一 1&00 ,0&10,ai<qmi(2,24),说明每个数最多操作25次 维护区间或和,orsum & x orsum 就不用递归下去了 势能线段树code // Problem: J. 二进制与、平方和 // Contest: Codeforc…...

LVS中NAT模式和DR模式实战讲解
1DR模式 DR:Direct Routing,直接路由,LVS默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部进行 转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源 IP/PORT…...

写给小白程序员的一封信
文章目录 1.编程小白如何成为大神?大学新生的最佳入门攻略2.程序员的练级攻略3.编程语言的选择4.熟悉Linux5.学会git6.知道在哪寻求帮助7.多结交朋友8.参加开源项目9.坚持下去 1.编程小白如何成为大神?大学新生的最佳入门攻略 编程已成为当代大学生的必…...

Leaf分布式ID
文章目录 系统对Id号的要求UUIDsnowflakeLeafLeaf-snowflakeLeaf-segmentMySQL自增主键segment双buffer 系统对Id号的要求 1、业务 1)全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求 2)趋势递增&a…...

Starrocks解析json数组
json数据 [{"spec": "70g/支","unit": "支","skuId": "1707823848651276346","amount": 6,"weight": 70,"spuName": "伊利 甄稀 苦咖啡味雪糕 流心冰淇淋 70g/支",&quo…...

安卓基本布局(下)
TableLayout 常用属性描述collapseColumns设置需要被隐藏的列的列号。shrinkColumns设置允许被伸缩的列的列号。stretchColumns设置允许被拉伸的列的列号。 <TableLayout xmlns:android"http://schemas.android.com/apk/res/android"android:id"id/TableL…...

Python中使用正则表达式
摘要: 正则表达式,又称为规则表达式,它不是某种编程语言所特有的,而是计算机科学的一个概念,通常被用来检索和替换某些规则的文本。 一.正则表达式的语法 ①行定位符 行定位符就是用来描述字符串的边界。"^&qu…...

三大口诀不一样的代码,小小的制表符和换行符玩的溜呀
# 小案例,打印输出加法口诀 for i in range(1,10):for j in range(1,10):if j>i:breakprint(f"{j}{i}{ji}".strip(),end\t)print() print(\n) for i in range(1,10):for j in range(1,10):if j>i:breakprint(f"{j}x{i}{j*i}",end\t)print…...
[qt] 线程等待与唤醒
对于生产者与消费者的数据处理的另一种好的解决方法是使用QWaitCondition类,允许线程在一定的条件下唤醒其他多个线程来共同处理。 一 定义公共变量 DataSize: 生产者生产数据的大小BufferSize: 也就是这个缓冲区的大小,每个单元是一个int,也有可能是一个链表,结构…...
Springboot 实现 Modbus Rtu 协议接入物联网设备
Modbus RTU 技术教程 引言 Modbus是一种开放标准的通信协议,它最初由Modicon(现施耐德电气)在1979年发布,旨在让可编程逻辑控制器(PLC)之间能够进行通信。随着时间的发展,Modbus已经成为工业自动化领域中最常用的通信协议之一,尤其适用于连接工业电子设备。本文将详细…...
鸿蒙笔记--装饰器
这一节主要了解一下鸿蒙里的装饰器,装饰器是一种特殊的语法结构,用于装饰类、结构体、方法以及变量; 1 Component在鸿蒙(HarmonyOS)开发中扮演着重要角色,主要用于定义可重用的UI组件,主要作用:1)组件化:Component装饰…...

不同环境下RabbitMQ的安装-3 操作RabbitMQ
前面两篇从不同环境下RabbitMQ的安装-1 为什么要使用消息服务 到同环境下RabbitMQ的安装-2 ARM架构、X86架构、Window系统环境下安装RabbitMQ介绍了关于如何在ARM架构、X86架构和Window系统下如何安装,各位小伙伴可以根据自己的实际开发场景参考安装。 到本篇是一些…...

postgregSQL配置vector插件
1.下载vector 下载vector:https://pgxn.org/dist/vector/0.5.1/ 放在:C:\Program Files\PostgreSQL\vector-0.5.1 2.安装Visual Studio 2022 下载:https://visualstudio.microsoft.com/zh-hans/downloads/ 安装Visual Studio是为了C编译环…...

PUMA论文阅读
PUMA: Efficient Continual Graph Learning with Graph Condensation PUMA:通过图压缩进行高效的连续图学习 ABSTRACT 在处理流图时,现有的图表示学习模型会遇到灾难性的遗忘问题,当使用新传入的图进行学习时,先前学习的这些模…...
算法学习day31(动态规划)
一、比特位计数 给你一个整数 n ,对于 0 < i < n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n 1 的数组 ans 作为答案。 输入:n 2 输出:[0,1,1] 解释:0 --> 0 1 --> 1 2 -…...

嵌入式学Day25---Linux软件编程---线程间通信
目录 编辑 一、线程的分离属性 1.1.什么是分离属性 1.2.分离属性相关函数接口 1.初始化线程属性-pthread_attr_init() 2.销毁线程属性-pthread_attr_destory() 3.设置线程属性-pthread_setdetachstate() 1.3.注意 二、互斥锁 2.1.资源 2.2.互斥锁 1.什么是互斥锁 2.互…...

【实现100个unity特效之17】在unity中使用shader和ShaderGraph分别实现模糊特定层,高斯模糊效果
最终效果 Unity通过Shader来模糊场景画面 参考:【游戏开发小技】Unity通过UI全屏图来模糊场景画面(Shader | 模糊 | 滤镜 | Blur) ShaderGraph实现图片的高斯模糊 参考:【游戏开发实战】Unity ShaderGraph实现图片的高斯模糊效…...

Unity补完计划 之 SpriteEditer Multiple
本文仅作笔记学习和分享,不用做任何商业用途 本文包括但不限于unity官方手册,unity唐老狮等教程知识,如有不足还请斧正 1. SpriteEditer Multiple Automatic slicing - Unity 手册 这是用于裁剪图集的模式 应用之后精灵编辑器会看到Slice亮…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...