模板初阶详解

目录

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

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 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.详细…

宝塔内 计划任务更新远程主机的时间

很多情况下一些主机无法上网,长此以往有可能让系统内的时间混乱 ,这是一个很愁人的事情 这里我们找了一个可以通过宝塔的计划任务或 cron 不断将本地时间通过ssh登录,并在登录状态下设置时间的方法.找了很多方案都不行 .最终采用了私钥登录的方案 1 使用宝塔的计划任务(可选): …

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…

Linux笔记之iftop查看特定IP地址吞吐量

Linux笔记之iftop查看特定IP地址吞吐量 code review! 文章目录 Linux笔记之iftop查看特定IP地址吞吐量一.iftop安装与监控二.iftop 界面简单介绍如何查看单位实时流量的显示形式控制单位显示示例 三.数据存储和传输的单位&#xff1a;比特&#xff08;bit&#xff09;和字节&…

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 }

AI机器人在未来的应用场景预测:是否会取代人类?华为、百度、特斯拉他们在AI领域都在做什么?

引言 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;AI机器人在各个领域的应用变得越来越普遍。从工业自动化到日常生活&#xff0c;AI机器人已经开始展现出强大的潜力和实际应用价值。本文将深入探讨AI机器人在未来的应用场景&#xff0c;并分析它们是否…

uniapp+vue3嵌入Markdown格式

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

大模型/NLP/算法面试题总结3——BERT和T5的区别?

1、BERT和T5的区别&#xff1f; BERT和T5是两种著名的自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;它们在架构、训练方法和应用场景上有一些显著的区别。以下是对这两种模型的详细比较&#xff1a; 架构 BERT&#xff08;Bidirectional Encoder Representation…

【Web前端】JWT(JSON Web Tokens)概述

1、简介 JWT&#xff08;JSON Web Tokens&#xff09;是一种用于双方之间安全传输信息的简洁的、URL安全的令牌标准。 它基于JSON对象&#xff0c;并通过数字签名确保其完整性和真实性。 JWT因其小巧、自包含以及易于在客户端和服务器之间传输的特性而被广泛使用于身份验证和…

python字符串验证从基础到进阶的总结

引言 在数据处理和文本挖掘中&#xff0c;对字符串的验证是确保数据符合特定要求的关键步骤之一。其中一个常见的验证需求是确认字符串是否只包含字母。Python为此提供了多种实现的方法&#xff0c;我们将逐一讨论它们。 方法1&#xff1a;使用 isalpha() 方法 def is_all_l…

UML 2.5图的分类

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

php简单实现利用飞书群里机器人推送消息的方法

这是一篇利用的飞书的自定义机器人&#xff0c;将系统中的错误信息推送给技术群的功能代码示例。 飞书文档地址&#xff1a;开发文档 - 飞书开放平台 自定义机器人只能在群聊中使用的机器人&#xff0c;在当前的群聊中通过调用webhook地址来实现消息的推送。 配置群逻辑可以看…

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

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