当前位置: 首页 > 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盘/移动硬盘、数…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

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