当前位置: 首页 > news >正文

模板初阶(详解)

一、泛型编程

为了引出模板,我们来看下面代码,比如要实现不同类型的交换函数,如下:

void Swap(int& a, int& b)
{int c = a;a = b;b = c;
}
void Swap(char& a, char& b)
{char c = a;a = b;b = c;
}
void Swap(double& a, double& b)
{double c = a;a = b;b = c;
}

        这样每个类型交换都需要写一个函数重载,其中代码的重复率很高,只有类型不同而逻辑都一样,写起来也非常的繁琐,那我们能不能写一个通用的函数告诉编译器一个模版让编译器根据不同的类型利用该模版来生成代码呢?这就是本章的主题——模板。

泛型编程编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。

模板分为函数模板和类模板,接下来我们分别来详细学习。

二、函数模版

函数模板的格式:

template<typename T1, typename T2 , ... ... ,typename Tn>

返回类型 函数名(参数列表){}

注意:这里typename可以换为calss,但不能换位struct。

代码示例:

template<typename T>
void Swap(T& a, T& b)
{T c = a;a = b;b = c;
}

        这样我们写一个模板就可以省了很多代码,还增加可读性。以上并不是一个函数只是一个模板,需要等到使用这个函数的时候编译器会具体的实例化出对应类型的函数,它和写多个函数重载并没有本质区别,只是说这个工作让编译器帮我们做了而已,在效率上并没有提升。

        需要注意的是如果在这里传两个不同的参数的话会编译报错,因为这里模板参数只有一个,而传入两个不同的类型的实参的时候,编译器并不会帮你强制类型转换,因为它并不知道转成那个类型出了问题它可不背锅。那么我们硬要传两个不同的参数的话,可以显示的强制类型转换成两个相同类型,或者调用的时候在函数名后面加<>,尖括号里面加类型名,也就是显示实例化

如下示例:

        这里有人可能会试图去测试Swap模板,结构还是编不过,这是因为不符合引用的语法,我在之前讲过,如下链接:

C++入门基础-CSDN博客

        对于这种情况,我们可以在外面进行强制类型转换存入新的变量里面然后再把新的变量代替原来变量做函数参数。 

        函数模板与模板函数的区别:通过这两个词就可以看出来函数模板的主语是模板,模板函数的主语是函数,那么接下来就好理解了,函数模板就是一个模板如刚才我们写的那些都是函数模板,而模板函数是函数模板经过实例化后生成的函数。

三、类模板

类模板的定义个格式:

template<typename T1, typename T2, ... ... ,typename Tn>

class 类模板名

{}

同样这里typename可以换为calss,但不能换位struct。

        对于类模板与函数模板不同,类模板在使用的时候必须显示实例化,在类模板名后面加<>尖括号里面放入类型名。

注意:类模板不是类,要经过实例化后才是类。如下一个Stack类模板的部分:

// 类模版
template<typename T>
class Stack
{
public :Stack(size_t capacity = 4){_array = new T[capacity];_capacity = capacity;_size = 0;} void Push(const T& data);//... ...
private:T* _array;size_t _capacity;size_t _size;
};
// 模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误
template<class T>
void Stack<T>::Push(const T& data)
{// 扩容//... ..._array[_size] = data;++_size;
} 
int main()
{Stack<int> st1;Stack<double> st2;return 0;
}

四、模板参数的匹配原则

接下来讲的匹配原则对于类模板和函数模板都是相同的,我们就以函数模板为例。

一个非模板函数是可以和模板函数同名的,而怎么区分编译器会调用那个呢,如下:

template<typename T>
T Add(T a, T b)
{return a + b;
}
int Add(int a, int b)
{return a + b;
}
int main()
{int a1 = 2, b1 = 4;double a2 = 2.5, b2 = 1.5;int ret1=Add(a1, b1);double ret2=Add(a2, b2);return 0;
}

        编译器在做调用(不仅指函数的调用)的时候有一个特点,有现成的就调现成的,没现成的就调用模板实例化一个。如这里第一个Add调用的是非模板函数,第二个Add调用的是模板函数。 

相关文章:

模板初阶(详解)

一、泛型编程 为了引出模板&#xff0c;我们来看下面代码&#xff0c;比如要实现不同类型的交换函数&#xff0c;如下&#xff1a; void Swap(int& a, int& b) {int c a;a b;b c; } void Swap(char& a, char& b) {char c a;a b;b c; } void Swap(doubl…...

对称加密算法解析:DES、AES及其在`pycryptodome` 和 `crypto-js` 模块中的应用

&#x1f4da; 对称加密算法解析&#xff1a;DES、AES及其在pycryptodome 和 crypto-js 模块中的应用 &#x1f5dd;️ DES 算法 算法原理 数据加密标准&#xff08;DES&#xff09;是一种对称密钥加密算法&#xff0c;用于保护数据的安全。DES 使用一个 56 位的密钥进行加密…...

C++设计模式(代理模式)

1. 电话虫 在海贼中&#xff0c;有一种神奇的通信工具叫做电话虫&#xff08;Den Den Mushi&#xff09;&#xff0c;外形如蜗牛&#xff0c;身上带有斑点或条纹或通体纯色&#xff0c;壳顶上有对讲机或按键&#xff0c;不接通时会睡觉&#xff0c;接通时会惊醒&#xff0c;并发…...

Linux系统驱动(十三)Linux内核定时器

文章目录 一、内核定时器原理二、定时器API三、使用定时器让LED灯闪烁四、使用定时器对按键进行消抖 一、内核定时器原理 内核当前时间通过jiffies获取&#xff0c;它是内核时钟节拍数&#xff0c;在linux内核启动的时候&#xff0c;jiffies开始&#xff08;按照一定频率&…...

Visual Studio 调试时加载符号慢

什么是调试符号 编译程序时生成的一组特殊字符&#xff0c;并包含有关变量和函数在生成的二进制文件中的位置以及其他服务信息的信息。 该数据集可用于逐步调试程序或检查第三方代码。 调试符号可以添加到可执行文件或库中&#xff0c;但是大多数现代编译器将它们存储为单独的…...

Spring Cloud Config:动态配置的魔法师

Spring Cloud Config&#xff1a;动态配置的魔法师 在微服务架构的浩瀚星海中&#xff0c;配置管理如同一颗璀璨的星辰&#xff0c;而Spring Cloud Config则是那颗能够实现配置信息集中管理和动态刷新的魔法星。本文将深入探索Spring Cloud Config的奥秘&#xff0c;揭示如何通…...

Webpack入门基础知识及案例

webpack相信大家都已经不陌生了&#xff0c;应用程序的静态模块打包工具。前面我们总结了vue&#xff0c;react入门基础知识&#xff0c;也分别做了vue3的实战小案例&#xff0c;react的实战案例&#xff0c;那么我们如何使用webpack对项目进行模块化打包呢&#xff1f; 话不多…...

对中国人工智能与国外人工智能的思考

作为一名语文老师&#xff0c;我在教育的领域中见证着时代的变迁&#xff0c;也关注着科技的发展&#xff0c;尤其是人工智能这一前沿领域。当我们将目光投向中国人工智能与国外人工智能的发展时&#xff0c;心中不禁涌起诸多思考。 中国的人工智能近年来犹如一颗璀璨的新星&am…...

【debian系统arm架构安装docker】且换源后依旧不行就离线导入镜像

安装docker 在Debian系统上安装Docker并使用阿里云的镜像源可以通过以下步骤完成 1.更新软件包索引 前置如果需要更换源的请移步 : 初始化配置(自动连wifi,自动开启SSH)换清华源,远程桌面连接 sudo apt-get update2.安装必要的软件包以允许apt通过HTTPS使用仓库 sudo apt-get …...

Readwise 官方 Obsidian 插件使用

Readwise 官方 Obsidian 插件简介 Obsidian 中的 Readwise 注释示例 阅读已经发布了官方插件来导入你的 Readwise 数据Obsidian 。如果你还没有使用过 Readwise&#xff0c;那么值得一看。Readwise 是我最喜欢的 应用之一。我每天都在用它。因此&#xff0c;将这些数据自动导…...

A. A+B Again?

time limit per test 1 second memory limit per test 256 megabytes Given a two-digit positive integer nn, find the sum of its digits. Input The first line contains an integer tt (1≤t≤901≤t≤90) — the number of test cases. The only line of each tes…...

pr样机模板视频素材|城市户外高速路广告牌视频样机

https://prmuban.com/40369.html pr样机素材&#xff0c;全高清实景城市户外高速路广告牌视频样机模板&#xff0c;适合宣传视频制作。 主要特点&#xff1a; Adobe Premiere Pro 2024 全高清分辨率&#xff08;19201080&#xff09; 易于使用 快速渲染 无需插件 预览中使用的…...

谷歌大中华区总裁:所有企业都在问这个问题

中国开发者对于出海的热情&#xff0c;令Google大中华区总裁陈俊廷感慨。2024 Google I/O Connect&#xff08;2024Google开发者大会&#xff09;期间&#xff0c;他在接受第一财经记者独家采访时提到一个细节&#xff1a;早上7:30&#xff0c;他来到会场时&#xff0c;人们已经…...

GPT-4o:AI视觉识别的革命性飞跃

在AI的宏伟叙事中&#xff0c;图像识别技术始终扮演着关键角色。随着技术的不断演进&#xff0c;AI的视界已超越了简单的图像内容识别&#xff0c;它现在能够将视觉信息转化为引人入胜的文字描述。OpenAI最新力作——GPT-4o模型&#xff0c;以其卓越的多模态理解能力&#xff0…...

将电脑打造成私人网盘,支持外网访问之详细操作教程

你想过把自己电脑打造成随时随地访问的网盘吗&#xff1f;就是那种拥有一个属于自己的影音库&#xff0c;不用担心被和谐&#xff0c;随时可以登录访问电脑上的各种文件&#xff0c;相比传统网盘省心又安全。 使用Everything和节点小宝将电脑搭建成私人网盘&#xff0c;可以实现…...

spring同一个接口如何分页实现主表或主+联表group by查询

1 需求背景 我们的上游系统想要知道主表的记录关联子表所有记录中是否有一条满足特定的条件&#xff0c;如果有满足的就返回主表中的id。比如品牌brand主表中id为10的记录&#xff0c;在子表brand_rel中有id为1&#xff0c;2&#xff0c;3&#xff0c;4的这四个记录&#xff0…...

SpringDataJpa源码分析

我们在定义Repository的时候通常定义的时一个接口&#xff0c;而并没有去实现这个接口&#xff0c;那么Jpa是如何让开发者无需自己实现接口就可以使用Repository去操作数据库&#xff1f; 动态代理&#xff01;&#xff01;&#xff01; Repository原理 试想一下JPA是如何做的…...

卷积神经网络 - 卷积神经网络与深度学习的历史篇

序言 卷积神经网络&#xff08; Convolutional Neural Networks, CNN \text{Convolutional Neural Networks, CNN} Convolutional Neural Networks, CNN&#xff09;与深度学习作为人工智能领域的两大重要分支&#xff0c;其发展历程充满了探索与突破。深度学习&#xff0c;作…...

初识 Floodfall 算法

文章目录 **一、Floodfall 算法的概述****二、深度优先搜索&#xff08;DFS&#xff09;和广度优先搜索&#xff08;BFS&#xff09;在 Floodfall 算法中的应用****三、算法的基本原理****四、应用场景** 一、Floodfall 算法的概述 Floodfall 算法通常用于解决与区域填充、图的…...

[Linux] LVM挂载的硬盘重启就掉的问题解决

问题&#xff1a;系统重启后挂在逻辑卷的盘会掉&#xff08;必现&#xff09; 环境&#xff1a;SUSE Linux 11 SP4 原因&#xff1a;boot.lvm是关闭的 解决&#xff1a;boot.lvm设置开启 参考资料&#xff1a; linux下lvm状态Not avaliable问题排查及处理(常见Suse操作系统…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...