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

C++——模板初阶

文章目录

  • 一.泛型编程
  • 二.函数模板
    • 1.函数模板的概念
    • 2.函数模板的格式
    • 3.函数模板的原理
    • 4.函数模板的实例化
      • (1)隐式实例化
      • (2)显式实例化
    • 5.模板参数的匹配原
  • 三.类模板
    • 1.类模板的定义格式
    • 2.类模板的实例化

前言:

本章我们将学习模板,正式接触泛型编程。C++相比于C语言有这么多丰富的接口与类型,都源于泛型编程。本章的内容为模板初阶知识,为接下来的STL学习打下坚实的基础。

一.泛型编程

如何实现一个通用的交换函数(swap)呢?我们已经学过函数重载的使用,函数重载在这种场景下作用很大:

void Swap(int& a, int& b)
{auto tmp = a;a = b;b = tmp;
}void Swap(double& a, double& b)
{auto tmp = a;a = b;b = tmp;
}void Swap(char& a, char& b)
{auto tmp = a;a = b;b = tmp;
}
//...

使用函数重载虽然可以实现,但是有一下几个不好的地方:

  1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数
  2. 代码的可维护性比较低,一个出错可能所有的重载均出错

那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?

  • 这就是我们今天要讲到的模板——模板是泛型编程的基础。模板不仅适用于函数,也适用于

二.函数模板

1.函数模板的概念

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

2.函数模板的格式

template<typename T1, typename T2,......,typename TN>
返回值类型 函数名(参数列表)
{//...函数体
}

示例:

template<typename T>
void Swap(T& a,T& b)
{auto tmp = a;a = b;b = tmp;
}
template<class N>
void Swap(N& a, N& b)
{auto tmp = a;a = b;b = tmp;
}

注意:

  1. typename后面的内容不一定是T,可自由指定;
  2. typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)

3.函数模板的原理

函数模板是一个描述的过程、一幅设计图、一个模板,并不是真正的函数。编译器会根据模板使用特定方式产生具体类型函数。所以其实模板就是将本来应该我们做的重复的事情交给了编译器去做(想想印刷术的原理)。

在这里插入图片描述

在编译器编译阶段,编译器需要根据传入的实参类型推演生成对应类型的函数以供调用。

比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。

4.函数模板的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化显式实例化

(1)隐式实例化

编译器根据实参推演模板参数的实际类型。

示例:

template<class T>
T Add(T a, T b)
{return  a + b;
}
void Test()
{int a = 10;int b = 100;cout << Add(a, b) << endl;
}

在这里插入图片描述

(2)显式实例化

在函数名后的<>指定模板参数的实际类型

错误示例:

template<class T>
T Add(T a, T b)
{return  a + b;
}void Test()
{int a = 10;double d = 3.14;cout << Add(a, d) << endl;
}

运行结果:

在这里插入图片描述

错误原因:

  • 因为在编译期间,当编译器看到该实例化时,需要推演其实参类型通过实参aT推演为int,通过实参dT推演为double类型,但模板参数列表中只有一个T,编译器无法确定此处到底该将T确定为int 或者 double类型而报错。

正确的做法

①显式实例化:就是在告诉编译器:不用你推演了,我已经指定这个类型了。

template<class T>
T Add(T a, T b)
{return  a + b;
}void Test()
{int a = 10;double d = 3.14;cout << Add<int>(a, d) << endl;
}

在这里插入图片描述

②使用多个模板参数

template<class T,class Y>
Y Add(T a, Y b)
{return  a + b;
}void Test()
{int a = 10;double d = 3.14;cout << Add(a, d) << endl;
}

在这里插入图片描述

注意:

  • 在下面情况中,两次调用的swap函数不是同一个函数!
template<class N>
void Swap(N& a, N& b)
{auto tmp = a;a = b;b = tmp;
}
void Test()
{int a = 10;int b = 100;Swap(a,b);char c1 = 'a';char c2 = 'b';Swap(c1, c2);
}

如下图所示汇编代码,显然两次调用的函数并不是一个函数(一个类型为Swap< int >,一个为Swap< char >)。事实上,虽然我们看不见这两份函数的代码,但是它们实实在在的产生了:

在这里插入图片描述

5.模板参数的匹配原

①一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数

template<class T>
T Add(T a, T b)
{return  a + b;
}int Add(int a, int b)
{return a + b;
}void Test()
{int a = 10;int b = 100;cout << Add<int>(a, b) << endl;
}

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

template<class T,class Y>
Y Add(T a, Y b)
{cout << "模板" << endl;return  a + b;
}
int Add(int a, int b)
{cout << "非模板" << endl;return a + b;
}
void Test()
{int a = 10;int b = 100;double d = 3.14;cout << Add(a, b) << endl;//使用非模板函数cout << Add(a, d) << endl;//使用模板
}

在这里插入图片描述

③模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

三.类模板

1.类模板的定义格式

template<class T1, class T2, ..., class Tn>
class 类模板名
{// 类内成员定义
};

示例:

template<class T>
class Stack
{
public://...
private:T* _a;size_t _size;size_t _capacity;
};

2.类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类

// Stack类名,Stack<int>是类型
Stack<int> s1;
Stack<double> s2

本文到此结束,码文不易,还请多多支持哦!

相关文章:

C++——模板初阶

文章目录 一.泛型编程二.函数模板1.函数模板的概念2.函数模板的格式3.函数模板的原理4.函数模板的实例化&#xff08;1&#xff09;隐式实例化&#xff08;2&#xff09;显式实例化 5.模板参数的匹配原 三.类模板1.类模板的定义格式2.类模板的实例化 前言&#xff1a; 本章我们…...

【TOOLS: Linux与windows及linux与linux之间文件传输常用方法及命令】

文章目录 1.1.1 Windows和VirtualBox(Ubuntu)之间文件穿传输方法1.1.2 SCP 文件传输方法1.1.3 FTP 文件传输方法 1.1.1 Windows和VirtualBox(Ubuntu)之间文件穿传输方法 1&#xff09;设置 virtualbox 中的共享文件夹&#xff0c;用户可以在windows某个盘下创建自己的共享文件…...

【博览群书】《实战大数据》——属于我的第一本大数据图书

文章目录 前言简介目录其他 前言 Hello家人们&#xff0c;博主前不久参加了CSDN图书馆和机械工业出版社联合举办的图书类活动&#xff0c;很荣幸在活动中获得了属于自己的第一本大数据图书&#xff0c;《实战大数据—— 分布式大数据分析处理系统开发与应用》。作为大数据专业…...

【计算机组成原理】实验二

文章目录 实验二 运算器实验一、实验目的二、实验原理三、运算器功能编码四、实验内容任务一 算术运算任务二 逻辑运算任务三 移位运算 实验二 运算器实验 一、实验目的 完成算术、逻辑、移位运算实验&#xff0c;熟悉ALU运算类型的控制位运用。实验仪器&#xff1a;JTHS-A …...

hive数据库hql基础操作02

1.内部表和外部表 默认情况下创建的表就是内部表&#xff0c;Hive拥有该表的结构和文件。换句话说&#xff0c;Hive完全管理表&#xff08;元数据和数据&#xff09;的生命周期&#xff0c;类似于RDBMS中的表。当你删除内部表时&#xff0c;它会删除数据以及表的元数据。可以使…...

门电路OD门

漏极开路输出的门电路&#xff08;OD门&#xff09; 为了满足输出电平的变换&#xff0c;输出大负载电流&#xff0c;以及实现“线与”功能&#xff0c;将CMOS门电路的输出级做成漏极开路的形式&#xff0c;称为漏极开路输出的门电路&#xff0c;简称OD&#xff08;Open&#x…...

没有域名,一个服务器Nginx怎么部署多个前端项目

因为没有域名&#xff0c;所以用路径来作区分&#xff0c; 主项目&#xff1a;直接根路由访问该项目&#xff0c;与正常配置无任何差别从项目&#xff1a;此处设置/new路径&#xff0c;为从项目&#xff0c;所有从项目访问路径均要加上/new ①修改Nginx配置文件 Nginx 配置文…...

城市内涝的原因和解决措施,内涝监测预警助力城市防涝度汛

城市内涝是城市化进程中最遇到的自然灾害&#xff0c;城市内涝不仅会对市民生活造成困扰&#xff0c;也会对城市基础设施和经济发展产生不利影响。因此&#xff0c;及时监测城市内涝现象&#xff0c;对于城市管理和城市安全具有重要意义。本文将深入探讨城市内涝的原因以及针对…...

8年测试总结,性能测试问题大全,这些问题你应该认清的...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 响应时间VS吞吐量…...

RabbitMQ集群安装

RabbitMQ集群安装 1.前言 OS: CentOS Linux release 7.9.2009 (Core) 机器: IPnodecpu内存存储10.106.1.241max-rabbitmg-018 核16 G100 G10.106.1.242max-rabbitmg-028 核16 G100 G10.106.1.243max-rabbitmg-038 核16 G100 G 因为操作系统版本是 centos7&#xff0c;所以…...

面试:link和@import的区别

1&#xff1a;link是XHTML标签&#xff0c;除了加载CSS外&#xff0c;还可以加载RSS&#xff1b;import只能加载CSS 2:link引入CSS时&#xff0c;在页面载入时同时加载&#xff1b;import需要页面完全载入后加载&#xff0c;可能会出行闪屏 3:link是XHTML标签&#xff0c;无兼容…...

图片隐写(一)

文件隐藏 binwalk binwalk -e filename foremost foremost filename steghide & stegseek Install sudo apt-get install steghidestegseek Use steghide extract -sf filename -p passwordtime stegseek secret.file aaa.txt dd 文本隐藏 二进制文件末尾 or 文…...

Vivado 下 IP核 之ROM 读写

目录 Vivado 下 IP核 之ROM 读写 1、实验简介 2、ROM IP 核简介 3、ROM IP 核配置 3.1、创建 ROM 初始化文件 3.2、单端口 ROM 的配置 3.3、双端口 ROM 的配置 3.4、ROM IP 核的调用 &#xff08;1&#xff09;ROM 顶层模块代码 &#xff08;2&#xff09;ROM IP 核仿…...

朗诵素材-《诵四季诗韵,咏师恩师德》

女&#xff1a;中华五千年的悠久历史&#xff0c;孕育了底蕴深厚的民族文化。 男&#xff1a;华夏源远流长的经典诗文&#xff0c; 女&#xff1a;是文化艺苑中经久不衰的瑰宝。 男&#xff1a;在那些脍炙人口的诗句里&#xff0c;凝聚着华光熠熠的民族精魂。 女&#xff1…...

CHB-麻省理工学院头皮脑电图数据库

数据库介绍 该数据库在波士顿儿童医院收集&#xff0c;包括患有顽固性癫痫发作的儿科受试者的脑电图记录。受试者在停用抗癫痫药物后被监测长达几天&#xff0c;以表征他们的癫痫发作并评估他们手术干预的候选资格。 数据库链接&#xff1a;https://physionet.org/content/chb…...

传输层协议

目录 传输层 端口号 端口号范围划分 认识知名端口号(Well-Know Port Number) netstat pidof UDP协议UDP协议端格式​编辑 UDP的特点 面向数据报 UDP的缓冲区 UDP使用注意事项 基于UDP的应用层协议 TCP协议 TCP协议段格式 确认应答(ACK)机制 超时重传机制 连…...

公司新招了个字节拿36K的人,让我见识到了什么才是测试扛把子......

5年测试&#xff0c;应该是能达到资深测试的水准&#xff0c;即不仅能熟练地开发业务&#xff0c;而且还能熟悉项目开发&#xff0c;测试&#xff0c;调试和发布的流程&#xff0c;而且还应该能全面掌握数据库等方面的技能&#xff0c;如果技能再高些的话&#xff0c;甚至熟悉分…...

pytorch rpc如何实现分物理机器的model parallel

因为业务需要&#xff0c;最近接到一项任务&#xff0c;是如何利用pytorch实现model parallel以及distributed training。搜罗了网上很多资料&#xff0c;以及阅读了pytorch官方的教程&#xff0c;都没有可参考的案例。讲的比较多的是data parallel&#xff0c;关于model paral…...

APP服务端架构的演变

大家好&#xff0c;我是易安&#xff01; 早期2013年的时候&#xff0c;随着智能设备的普及和移动互联网的发展&#xff0c;移动端逐渐成为用户的新入口&#xff0c;各个电商平台都开始聚焦移动端App&#xff0c;如今经历了10年的发展&#xff0c;很多电商APP早已经没入历史的洪…...

EasyRecovery16适用于Windows和Mac的专业硬盘恢复软件

无论你对数据恢复了解多少&#xff0c; 我们将为您处理所有复杂的流程并简化恢复!适用于Windows和Mac的 专业硬盘恢复软件 硬盘数据无法保证绝对安全。有时会发生数据丢失&#xff0c;需要使用硬盘恢复工具。支持恢复不同存储介质数据&#xff1a;硬盘、光盘、U盘/移动硬盘、数…...

Qwen3-ASR-1.7B开发入门:MySQL数据库集成教程

Qwen3-ASR-1.7B开发入门&#xff1a;MySQL数据库集成教程 1. 引言 语音识别技术正在改变我们与设备交互的方式&#xff0c;而将识别结果持久化存储是许多实际应用的关键需求。今天我们来聊聊如何将Qwen3-ASR-1.7B这个强大的语音识别模型与MySQL数据库结合起来&#xff0c;让你…...

论文阅读:arxiv 2026 Uncovering Security Threats and Architecting Defenses in Autonomous Agents: A Case S

总目录 大模型安全研究论文整理 2026年版&#xff1a;https://blog.csdn.net/WhiffeYF/article/details/159047894 Uncovering Security Threats and Architecting Defenses in Autonomous Agents: A Case Study of OpenClaw https://arxiv.org/abs/2603.12644 该论文《Uncov…...

新手也能搞定的应急响应实战:用知攻善防靶场复现近源渗透与挖矿事件

新手也能搞定的应急响应实战&#xff1a;用知攻善防靶场复现近源渗透与挖矿事件 网络安全应急响应是每个安全从业者的必修课&#xff0c;但对于刚入门的新手来说&#xff0c;面对真实的攻击事件往往无从下手。本文将带你通过知攻善防靶场&#xff0c;手把手复现"近源渗透O…...

各种 32 位单片机(MCU),本质上是围绕不同 CPU 内核、由不同厂商设计的 32 位微控制器家族,最主流的是基于 ARM Cortex‑M 内核的各类兼容 / 派生系列,其次是少数自研内核架构。

一、按内核架构&#xff1a;两大阵营1. ARM Cortex‑M 内核&#xff08;绝对主流&#xff0c;占 90% 以上市场&#xff09;所有基于 ARM 公司授权的 Cortex‑M 系列处理器内核 的 MCU。内核谱系&#xff08;从低到高&#xff09;&#xff1a;Cortex‑M0 / M0&#xff1a;入门、…...

计算机毕业设计:Python气象数据可视化与采集管理系统 Flask框架 数据分析 可视化 爬虫 气象数据分析(建议收藏)✅

博主介绍&#xff1a;✌全网粉丝50W&#xff0c;前互联网大厂软件研发、集结硕博英豪成立软件开发工作室&#xff0c;专注于计算机相关专业项目实战6年之久&#xff0c;累计开发项目作品上万套。凭借丰富的经验与专业实力&#xff0c;已帮助成千上万的学生顺利毕业&#xff0c;…...

保姆级教程:手把手教你将中国土地利用栅格数据(GRID/TIFF)转换成WRF能用的二进制格式(含GDAL和index文件配置避坑指南)

从GRID到二进制&#xff1a;WRF土地利用数据转换全流程实战指南 当你在深夜盯着屏幕&#xff0c;反复检查那些令人头疼的GDAL命令和index文件参数时&#xff0c;是否曾希望有人能一步步带你走出这个迷宫&#xff1f;作为WRF模拟中最为基础却又最容易出错的环节&#xff0c;土地…...

Hinge损失函数:从SVM的基石到现代机器学习中的间隔优化

1. Hinge损失函数的前世今生 第一次听说Hinge损失函数是在研究生时期的一堂机器学习课上。教授在黑板上画了一条直线&#xff0c;说这就是SVM的决策边界&#xff0c;而Hinge损失就是确保这条线能"站稳脚跟"的关键。当时觉得这个比喻特别形象——就像门上的铰链&#…...

ID12RFID库详解:嵌入式125kHz RFID读卡实践指南

1. ID12RFID 库深度解析&#xff1a;面向嵌入式系统的 125kHz RFID 标签读取实践指南ID12RFID 是一个专为嵌入式平台设计的轻量级 C/C 库&#xff0c;用于驱动 ID-12&#xff08;及兼容型号如 ID-20、RDM6300&#xff09;系列 125kHz 低频 RFID 模块。该模块采用 ASK 调制方式&…...

嵌入式系统软件抗干扰技术实战解析

1. 嵌入式系统抗干扰技术概述在工业控制、智能家居和物联网设备等嵌入式应用场景中&#xff0c;电磁干扰、电源波动等环境因素常常导致系统运行异常。作为一名有十年嵌入式开发经验的工程师&#xff0c;我处理过数十起由干扰引起的系统故障案例。硬件抗干扰措施如屏蔽、滤波固然…...

飞跨电容三电平拓扑的实战解析:从数学原理到SiC MOSFET的高频设计

1. 飞跨电容三电平拓扑的数学起源 飞跨电容三电平&#xff08;FCML&#xff09;拓扑的命名并非随意&#xff0c;它实际上植根于18世纪的数学拓扑学。数学拓扑学研究的是几何图形在连续变形下保持不变的性质&#xff0c;这个概念最早由欧拉在1736年研究柯尼斯堡七桥问题时提出。…...