模板初阶详解

目录

  • 泛型编程
  • 函数模板
    • 函数模板概念
    • 函数模板格式
    • 函数模板的原理
    • 函数模板的实例化
      • 隐式实例化
        • 强制类型转换的疑惑
      • 显式实例化
    • 模板参数的匹配原则
  • 类模板
    • 类模板的定义格式
    • 类模板的实例化

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐣🐣 python
🐓🐓🐓 数据结构C语言
🐔🐔🐔 C++
🐿️🐿️🐿️ 文章链接目录

泛型编程

下面是实现各种类型的交换函数

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;
}

上面函数功能完全相同,只是传入的参数类型不同,如果我们在要一一实现的话就太麻烦了,所以如果有一个公用的模板,可以支持不同类型的传参就好了

函数模板

函数模板概念

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

函数模板格式

template<typename T1, typename T2,......,typename Tn>这里的T1..代表类型

用函数模板实现交换功能如下

template<typename T>
void Swap( T& left, T& right)
{T temp = left;left = right;right = temp;
}

在这里插入图片描述
T代表所有的类型,所以也可以交换char类型的变量
在这里插入图片描述

注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)

函数模板的原理

上面的模板中不同类型的变量都调用了Swap,现在有一个问题就是Swap(a,b)和Swap(c,d)是否用的同一个Swap函数

事实上他们调用的并不是同一个Swap函数,因为a b的类型和c d的类型是不一样的,也就是函数模版中的T是未知类型,根据传入参数类型生成一个匹配的函数

函数模板的实例化

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

隐式实例化

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

在上面已经演示过一个例子了
在这里插入图片描述
但是如果我们传入的参数不符合模板规定就会报错
在这里插入图片描述
这里的Swap模板中的T只能表示一种类型,而我们传入的参数中包含了int类型和double类型,也就是说T的类型即是int也是double,显然这是不可能的,所以出现参数T不明确这个错误

解决方案有三种,第一种是强制类型转换,第二种就是显示实例化,第三种就是用多个不同的T(T1 T2 T3…)

强制类型转换的疑惑

但是关于强制类型转换这里我有一点疑惑

void Swap(T& left, T& right)
{T temp = left;left = right;right = temp;
}
int main()
{int a = 1, b = 2;double c = 1.001, d = 2.001;Swap(a, b);Swap((int)c, a);cout << a << "\n" << b << endl;cout << c << "\n" << d << endl;return 0;
}

在这里插入图片描述
按理来说强制类型转换后参数类型就相同了,并且就算double类型和int类型数据进行交换,也应该只是出现数据丢失这种情况,但是不会报错,而这里却出现了问题,所以我不是很清楚

而再看看下面这个例子,在没有强制类型转换前是报错的,而强制类型转换后可以正常运行
在这里插入图片描述
在这里插入图片描述

显式实例化

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

template<typename T1>
T1 ADD(const T1& left, const T1 right)
{return left + right;
}
int main()
{int a = 1;double b = 2.001;cout << ADD<int>(a, b) << endl;cout << ADD<double>(a, b) << endl;return 0;
}

在这里插入图片描述
Swap函数还是会报错,但是后面我发现了一句话:如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错,可能是因为这个才报错的
在这里插入图片描述
但是第三中方法是可以解决这个问题的

template<typename T1,typename T2>
T1 ADD(const T1& left, const T2 right)
{return left + right;
}
int main()
{int a = 1;double b = 2.001;cout << ADD(a, b) << endl;return 0;
}

这里会出现数据丢失,所以输出的结果是3
在这里插入图片描述
再来看看Swap会不会报错

template<typename T,typename T1>
void Swap(T& left, T1& right)
{T temp = left;left = right;right = temp;
}int main()
{int a = 1, b = 2;double c = 1.001, d = 2.001;Swap(a, b);Swap(c, a);cout << a << "\n" << b << endl;cout << c << "\n" << d << endl;return 0;
}

c之所以等于2是因为c在交换前,a和b已经交换了,所以c在和a交换的时候其实是1.001和2交换
而a之所以等于1,是因为在c和a交换后,a为1.001,然后因为a是int类型导致数据丢失
在这里插入图片描述

模板参数的匹配原则

template<typename T>
T ADD(const T& left, const T& right)
{return left + right;
}
int ADD(const int& left, const int& right)
{return left + right;
}
int main()
{int a = 1, b = 2;cout << ADD(a, b) << endl;return 0;
}

这段代码可以正常运行,但是现在又一个问题就是两个ADD函数,一个是通用模板,另一个是现成的函数,到底是用的哪一个呢?
在这里插入图片描述

显然为偷懒,当然是用现成的函数,所以我们调用的函数是先从的ADD函数

而下面这种就不是调用现成的ADD函数了,因为这里用了显示实例化,也就表示了你必须调用模板函数,让T变成int类型,即使有现成的函数也不可以偷懒

在这里插入图片描述

类模板

类模板的定义格式

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

类模板的实例化

来看看下面的例子

template<typename T>
class A
{
public:T ADD(const T& left, const T& right){return left + right;}
private:T a;int b;
};
int main()
{int c = 0, d = 2;double e = 0.0001, f = 1.0001;A <int>a;A<double>b;cout << a.ADD(c, d) << endl;cout << b.ADD(e, f) << endl;return 0;
}

类模版的实例化都是显示实例化,也就是在定义的时候我们就要规定T是什么类型,例如A < int> a表示这a这个对象中T是int类型,其次类中的函数也是和之前的模板函数一样的
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/44087.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序接口wx.getLocation违规导致封禁解决办法

1、找到站内信的这个封禁的通知&#xff08;功能封禁的通知&#xff0c;而不是处理警告的通知&#xff09; 2、点击通知会有申诉链接&#xff0c;点开申诉链接 申诉原因可参考下面的内容&#xff1a; 1.小程序哪些板块已除去收集地理位置、2.哪些板块需要收集地理位置、3.详细…

WindowsMac共享文件夹设置

共享文件夹设置 共享文件夹设置Windows系统设置步骤一&#xff1a;设置共享文件夹步骤二: 访问共享文件夹 Mac系统中设置共享文件夹步骤一&#xff1a;设置共享文件夹步骤二&#xff1a;访问共享文件夹 小贴士结论 共享文件夹设置 有时需要在多台电脑之间共享文件夹&#xff0…

4.MkDocs样式

学习 Admonitions(警告) - Material for MkDocs (wdk-docs.github.io) 提示 - Material for MkDocs 中文文档 (llango.com) Buttons(按钮) - Material for MkDocs (wdk-docs.github.io) 建议去看这些网站&#xff0c;更为详细。 常用功能 便利贴 ​​ 开启 markdown_ex…

Gemma2——Google 新开源大型语言模型完整应用指南

0.引言 Gemma 2以前代产品为基础&#xff0c;提供增强的性能和效率&#xff0c;以及一系列创新功能&#xff0c;使其在研究和实际应用中都具有特别的吸引力。Gemma 2 的与众不同之处在于&#xff0c;它能够提供与更大的专有模型相当的性能&#xff0c;但其软件包专为更广泛的可…

hdfs大规模数据存储底层原理详解(第31天)

系列文章目录 一、HDFS设计原理 二、HDFS系统架构 三、HDFS关键技术 四、HDFS应用实例 五、解决HDFS不能处理小文件详解问题 文章目录 系列文章目录前言一、设计原理二、系统架构三、关键技术四、应用实例五、解决HDFS不能处理小文件详解问题1. 合并小文件2. 优化Hive配置3. 使…

DDR3 SO-DIMM 内存条硬件总结(一)

最近在使用fpga读写DDR3&#xff0c;板子上的DDR3有两种形式与fpga相连&#xff0c;一种是直接用ddr3内存颗粒&#xff0c;另一种是通过内存条的形式与fpga相连。这里我们正好记录下和ddr3相关的知识&#xff0c;先从DDR3 SO-DIMM 内存条开始。 1.先看内存条的版本 从JEDEC下载…

Mysql练习题目【7月10日更新】

七、Mysql练习题目 https://zhuanlan.zhihu.com/p/38354000 1. 创建表 创建学生表 mysql> create table if not exists student(-> student_id varchar(255) not null,-> student_name varchar(255) not null,-> birthday date not null,-> gender varchar(…

前端面试题33(实时消息传输)

前端实时传输协议主要用于实现实时数据交换&#xff0c;特别是在Web应用中&#xff0c;它们让开发者能够构建具有实时功能的应用&#xff0c;如聊天、在线协作、游戏等。以下是几种常见的前端实时传输协议的讲解&#xff1a; 1. Short Polling (短轮询) 原理&#xff1a;客户…

【1】A-Frame整体介绍

1.A-Frame是什么&#xff1f; A-Frame 是一个用于构建虚拟现实 (VR) 体验的 Web 框架。 A-Frame 基于 HTML 之上&#xff0c;因此上手简单。但 A-Frame 不仅仅是 3D 场景图或标记语言&#xff1b;它还是一种标记语言。其核心是一个强大的实体组件框架&#xff0c;为 Three.js …

Golang | Leetcode Golang题解之第226题翻转二叉树

题目&#xff1a; 题解&#xff1a; func invertTree(root *TreeNode) *TreeNode {if root nil {return nil}left : invertTree(root.Left)right : invertTree(root.Right)root.Left rightroot.Right leftreturn root }

uniapp+vue3嵌入Markdown格式

使用的库是towxml 第一步&#xff1a;下载源文件&#xff0c;那么可以git clone&#xff0c;也可以直接下载压缩包 git clone https://github.com/sbfkcel/towxml.git 第二步&#xff1a;设置文件夹内的config.js&#xff0c;可以选择自己需要的格式 第三步&#xff1a;安装…

UML 2.5图的分类

新书速览|《UML 2.5基础、建模与设计实践》新书速览|《UML 2.5基础、建模与设计实践 UML 2.5在UML 2.4.1的基础上进行了结构性的调整&#xff0c;简化和重新组织了 UML规范文档。UML规范被重新编写&#xff0c;使其“更易于阅读”&#xff0c;并且“尽可能减少前向引用”。 U…

LLM应用构建前的非结构化数据处理(三)文档表格的提取

1.学习内容 本节次学习内容来自于吴恩达老师的Preprocessing Unstructured Data for LLM Applications课程&#xff0c;因涉及到非结构化数据的相关处理&#xff0c;遂做学习整理。 本节主要学习pdf中的表格数据处理 2.环境准备 和之前一样&#xff0c;可以参考LLM应用构建前…

金蝶部署常见问题解决

金蝶部署常见问题解决 金蝶版本&#xff1a; Apusic Application Server Enterprise Edition 9.0 SP8 kbc build 202312041121 报错信息&#xff1a; 与金蝶官方人员沟通&#xff0c;发现lib包版本太低&#xff0c;升级后可正常使用。替换lib包后重启服务。 下载lib: 链接: …

西瓜杯CTF(1)

#下班之前写了两个题&#xff0c;后面继续发 Codeinject <?php#Author: h1xaerror_reporting(0); show_source(__FILE__);eval("var_dump((Object)$_POST[1]);"); payload 闭合后面的括号来拼接 POST / HTTP/1.1 Host: 1dc86f1a-cccc-4298-955d-e9179f026d54…

公司内部配置GitLab,通过SSH密钥来实现免密clone、push等操作

公司内部配置GitLab&#xff0c;通过SSH密钥来实现免密clone、push等操作。以下是配置SSH密钥以实现免密更新的步骤&#xff1a; 1.生成SSH密钥 在本地计算机上打开终端或命令提示符。输入以下命令以生成一个新的SSH密钥&#xff1a;ssh-keygen -t rsa -b 4096 -C "your…

VBA实现Excel数据排序功能

前言 本节会介绍使用VBA如何实现Excel工作表中数据的排序功能。 本节会通过下表数据内容为例进行实操&#xff1a; 1. Sort 单列排序 语法&#xff1a;Sort key1,Order1 说明&#xff1a; Key1&#xff1a;表示需要按照哪列进行排序 Order1&#xff1a;用来指定是升序xlAsce…

D2D用户的功率优化算法研究

D2D通信技术是指两个对等的用户节点之间直接进行通信的一种通信方式。在由D2D通信用户组成的分布式网络中&#xff0c;每个用户节点都能发送和接收信号&#xff0c;并具有自动路由(转发消息)的功能。网络的参与者共享它们所拥有的一部分硬件资源&#xff0c;包括信息处理、存储…

短视频矩阵搭建,用云微客获客更方便

你的同行都爆单了&#xff0c;你还在问什么是矩阵&#xff1f;让我来告诉你。短视频矩阵是短视频获客的一种全新玩法&#xff0c;是以品牌宣传、产品推广为核心的一个高端布局手段&#xff0c;也是非常省钱的一种方式。 1.0时代&#xff0c;一部手机一个账号&#xff1b;2.0时代…

GD 32中断系统实现

1.0 中断的概念 中断&#xff1a;简单来说就是打断的意思&#xff0c;在计算机系统中CPU在执行一个操作的时候&#xff0c;有一个比当前任务更为紧急的任务需要执行,cpu暂停当前任务转而去执行更为紧急任务的操作&#xff0c;执行完更为紧急任务之后再返回来执行原来未执行完的…