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

《模版初阶》

引言:

上次我们学习了内存管理,之后就要开始学STL了,但是在学习STL之前,我们还需要有一个前置知识->模版,只不过这里只是对模版有一个初步认知,后面还会深入学习。

一:泛型编程

如何实现一个让各种类型通用的交换函数呢?
这时很容易想到之前学过的函数重载,下面是函数重载实现:
在这里插入图片描述

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

  1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数。
  2. 代码的可维护性比较低,一个出错可能所有的重载均出错。
    那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?

有的兄弟,有的,下面就来引入泛型编程这一概念:

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。
模板是泛型编程的基础
在这里插入图片描述

二:函数模版

1. 概念

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

2. 形式

template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表){}
在这里插入图片描述

注意typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)
在这里插入图片描述

3. 函数模版原理

函数模版就相当于是一个蓝图,将需要进行的重复性工作交给了编译器,编译器根据这个模版会生成不同类型(功能相同)的模版函数来解决问题。
在这里插入图片描述
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。

4. 函数模版的实例化

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

(1) 隐式实例化:让编译器根据实参推演模板参数的实际类型

在这里插入图片描述由于隐式实例化时编译器不会自动进行类型转换,因此当编译器无法统一实参的类型时就会编译出错,如果转换出错的话编译器不是还得背锅吗。
比如这种情况下:
在这里插入图片描述

这时候可以自己进行强转,也可以使用显示实例化
先来看强转:
在这里插入图片描述

(2)显示实例化:在函数名后的<>中指定模板参数的实际类型

在这里插入图片描述

(3)小结:

如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。

5. 模板参数的匹配原则

(1)有成品就用成品

在这里插入图片描述
在这里插入图片描述
:这里在Add函数模版与整形的Add函数同时存在时,编译器会优先使用已有的,因为没有double类型的Add函数,因此编译器还是会自己生成。

但是如果你想调用编译器自己生成的加法函数的话就可以显示实例化
在这里插入图片描述

(2)优先使用最匹配的函数

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

比如下面这个场景:
在这里插入图片描述

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

三:类模板

1. 格式

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

2. 举例

这里我们拿之前实现的栈来举例:
在这里插入图片描述
这个是之前实现的栈结构,如果我们现在需要创建不同的栈来存储不同类型的数据的话,就需要写额外的栈结构,因为之前实现的栈的数据类型是一键替换的,只支持一种类型。

下面是用类模版来实现的栈:
在这里插入图片描述
这个时候想创建不同的栈来存储数据的话就不需要写额外的栈结构了,因为编译器会根据这个栈的类模板去生成相应的栈来让我们使用。

3. 类模版的实例化

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

在这里插入图片描述

四:完结

http://www.xdnf.cn/news/6564.html

相关文章:

  • matlab多项式
  • 【unity游戏开发——编辑器扩展】EditorGUIUtility提供一些 EditorGUI 相关的其他辅助API
  • 车载诊断架构 ---车载总线对于功能寻址的处理策略
  • 北京孙河傲云源墅:限量典藏的主城墅居臻品
  • 3.3 掌握RDD分区
  • 密码学刷题小记录
  • 一物一码赋能智能制造:MES如何实现生产全流程数字化追溯
  • JAVA单元测试、反射
  • 在ubuntu系统中将vue3的打包文件dist 部署nginx 并且配置ssl证书 以https方式访问
  • 2025年5月15日
  • 广度和深度优先搜索(BFS和DFS)
  • Ubuntu20.04下如何源码编译Carla,使用UE4源码开跑,踩坑集合
  • Secs/Gem第七讲(基于secs4net项目的ChatGpt介绍)
  • 驱动-Linux定时-timer_list
  • ollama 重命名模型
  • 每日一道leetcode(新学数据结构版)
  • CISA 备考通关经验及回忆题分享
  • 1:OpenCV—图像基础
  • python打卡day26
  • 【开源Agent框架】OWL:面向现实任务自动化的多智能体协作框架深度解析
  • 从代码学习深度学习 - 风格迁移 PyTorch版
  • 中国科学院计算所:从 NFS 到 JuiceFS,大模型训推平台存储演进之路
  • 【知识点】大模型面试题汇总(持续更新)
  • SQLPub:一个提供AI助手的免费MySQL数据库服务
  • 智慧化系统安全分析报告
  • AI学习博文链接
  • 12V升24V升压恒压WT3207
  • YOLO格式数据集制作以及训练
  • c++多态面试题之(析构函数与虚函数)
  • 工业操作系统核心技术揭秘