网站服务器租用一般费用/seo免费优化软件
文章目录
- 1.编程范式
- 2.函数模板
- 2.1 函数模板概念
- 2.2 函数模板原理
- 2.3 函数模板实例化
- 2.3.1 隐式实例化
- 2.3.2 显式实例化
- 2.4 模板参数的匹配原则
- 3.类模板
- 希望读者们多多三连支持
- 小编会继续更新
- 你们的鼓励就是我前进的动力!
进入STL库学习之前我们要先了解有关模板的学习,以便在学习完STL库使用之后,能更深入的了解其底层工作原理
1.编程范式
编程范式
指的是我们使用编程的基本风格和方法
常见的方式有以下几种:
面向对象编程(OOP)
将数据和操作数据的方法封装在类中,通过类的实例(对象)来进行交互,强调数据的封装、继承和多态性
定义一个Shape
基类,包含计算面积的纯虚函数,再派生出Circle
和Rectangle
等类,重写计算面积的函数,体现了面向对象的继承
和多态
特性
函数式编程
将计算视为函数的组合和应用,强调不可变数据和纯函数,避免副作用,注重函数的输入输出关系
使用std::function
和lambda
表达式可以方便地进行函数式编程,如用lambda
表达式定义一个简单的加法函数
,不修改外部状态,只返回计算结果
过程式编程
以过程(函数)为中心,将程序分解为一系列的步骤和函数调用,数据和操作数据的函数相对独立
传统的C语言
风格的编程方式,如编写一个计算阶乘的函数,通过循环
和递归
来实现计算过程,就是典型的过程式编程
泛型编程
定义函数、类或其他程序结构时,不指定具体的数据类型,而是使用类型参数来代表未知的数据类型
在algorithm
头文件中的swap
函数就是一种常见的泛式编程,他不指定任何类型就能实现交换,依靠的就是泛式编程,也是我们接下来要学习的模板
2.函数模板
在还不知道头文件前实现swap函数
通常是这样的:
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;
}......
为了符合各个场景下实现参数互换,要对同一个函数实现不同类型的函数重载
,这种方式固然可行,但是每个类型都写一遍太过于冗余了
- 重载的函数仅仅是
类型不同
,代码复用率比较低
,只要有新类型出现时,就需要用户自己增加对应的函数 - 代码的
可维护性比较低
,一个出错可能所有的重载均出错
2.1 函数模板概念
我们知道文字的印刷是依靠活字印刷术的模板实现的,那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?
这里用到的模板就是函数模板
,其语法形式为:
template<typename T1, typename T2,......,typename Tn>
template
就是模板的意思,是用来定义模板参数关键字,也可以使用class
,切记:不能使用struct
代替class
,因为struct
和class
的默认权限不同,会导致一些混淆和潜在的问题
2.2 函数模板原理
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器
举个例子:
template<typename T>
void Swap(T& a, T& b)
{T temp = a;a = b;b = temp;
}
实现一个Swap交换函数
对两个不同类型的函数进行同一个函数的调用,调试模式下转到反汇编可以发现,两个函数式模板示例化后被调用的
这直接说明了调用的不是同一个函数
在编译器编译阶段
,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数
以供调用。
比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码
,这个类型无论是内置类型
还是自定义类型
都可以
2.3 函数模板实例化
用不同类型的参数使用函数模板时,称为函数模板的实例化
2.3.1 隐式实例化
让编译器根据实参推演模板参数的实际类型
叫作隐式实例化
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}int main()
{int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add(a1, a2);Add(d1, d2);return 0;
}
正常情况下的调用就是隐式实例化
🔥值得注意的是: Add函数前加const是因为这里如果像下面例子一样进行强制转化会生成临时变量,具有常性
该知识点在前面有提到过:
传送门:C++命运石之门代码抉择:C++入门(中)
2.3.2 显式实例化
在函数名后的<>中指定模板参数的实际类型
叫作显式实例化
Add(a1, d1);
还是上面的例子,如果既调用int,又调用double,到底是用哪种类型编译器无法决定
,就需要显式实例化
🚩用户自己来强制转化
Add(a1, (int)d1);
🚩使用显式实例化
Add<int>(a1, d1);
指定T的类型为int
这通常不是显式实例化的常用场景,举个例子:
template<class T>
T* Alloc(int n)
{return new T[n];
}int main()
{Alloc<int>(5);return 0;
}
如果写成Alloc(5)
,编译器不知道你要分配的是int数组
、double数组
还是其他类型的数组,所以无法自动推导T的类型
,这时候就需要显式指定模板参数,像Alloc<int>(5)
这样明确告诉编译器T是int类型
2.4 模板参数的匹配原则
🚩一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数
// 专门处理int的加法函数
int Add(int left, int right)
{return left + right;
}// 通用加法函数
template<class T>
T Add(T left, T right)
{return left + right;
}void Test()
{Add(1, 2); // 与非模板函数匹配,编译器不需要特化Add<int>(1, 2); // 调用编译器特化的Add版本
}
🚩对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板
// 专门处理int的加法函数
int Add(int left, int right)
{return left + right;
}// 通用加法函数
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{return left + right;
}void Test()
{Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化Add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数
}
🚩模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
这里的自动转化就是上面的实例化中的转化,也要和auto自动推导区分开,不是同一个东西
3.类模板
类模板其实和函数模板是类似的
其语法形式为:
template<class T1, class T2, ..., class Tn>
因为类不像函数那样语法上支持自动类型转化,所以类模板调用必须显式实例化
// 动态顺序表
// 注意:Vector不是具体的类,是编译器根据被实例化的类型生成具体类的模具
template<class T>
class Vector
{
public:Vector(size_t capacity = 10): _pData(new T[capacity]), _size(0), _capacity(capacity){}// 使用析构函数演示:在类中声明,在类外定义。~Vector();void PushBack(const T& data);void PopBack();// ...size_t Size() { return _size; }T& operator[](size_t pos){assert(pos < _size);return _pData[pos];}private:T* _pData;size_t _size;size_t _capacity;
};
// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{if (_pData)delete[] _pData;_size = _capacity = 0;
}int main()
{// Vector类名,Vector<int>才是类型Vector<int> s1;Vector<double> s2;return 0;
}
我们在写模板类时尽量不要声明定义分离
,原因有些复杂放在模板进阶的时候讲,如果一定分离的话要注意:
- 对于
普通类
,类名和类型一样 - 对于
模板类
,Vector类名
,Vector<int>才是类型
希望读者们多多三连支持
小编会继续更新
你们的鼓励就是我前进的动力!
相关文章:

C++底层学习预备:模板初阶
文章目录 1.编程范式2.函数模板2.1 函数模板概念2.2 函数模板原理2.3 函数模板实例化2.3.1 隐式实例化2.3.2 显式实例化 2.4 模板参数的匹配原则 3.类模板希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力! 进入STL库学习之前我们要先了解有关模板的…...

使用mybatisPlus插件生成代码步骤及注意事项
使用mybatisPlus插件可以很方便的生成与数据库对应的PO对象,以及对应的controller、service、ImplService、mapper代码,生成这种代码的方式有很多,包括mybatis-plus提供的代码生成器,以及idea提供的代码生成器,无论哪一…...

扩散模型(二)
相关阅读:扩散模型(一) Parameterization of L t L_t Lt for Training Loss 回想一下,我们需要训练一个神经网络来近似反向扩散过程中的条件概率分布,即, p θ ( x t − 1 ∣ x t ) N ( x t − 1 ; μ θ ( x t…...

java异常处理——try catch finally
单个异常处理 1.当try里的代码发生了catch里指定类型的异常之后,才会执行catch里的代码,程序正常执行到结尾 2.如果try里的代码发生了非catch指定类型的异常,则会强制停止程序,报错 3.finally修饰的代码一定会执行,除…...

新月军事战略分析系统使用手册
新月人物传记: 人物传记之新月篇-CSDN博客 相关故事链接:星际智慧农业系统(SAS),智慧农业的未来篇章-CSDN博客 “新月智能武器系统”CIWS,开启智能武器的新纪元-CSDN博客 “新月之智”智能战术头盔系统&…...

Docker Hub 镜像 Pull 失败的解决方案
目录 引言一、问题二、原因三、解决方法四、参考文献 引言 在云原生技术火热的当下,Docker可谓是其基础,由于其简单以及方便性,让开发人员不必再为环境配置问题而伤脑筋,因为可将其看作一个虚拟机程序去理解。所以掌握好它可谓是…...

SQL进阶实战技巧:如何构建用户行为转移概率矩阵,深入洞察会话内活动流转?
目录 1 场景描述 1.1 用户行为转移概率矩阵概念 1.2 用户行为转移概率矩阵构建方法 (1) 数据收集...

DeepSeek辅助学术写作关键词选取
关键词 关键词主要从论文标题、摘要及正文中提炼出来,需要准确反映论文的核心主题和专业领域。关键词的选择不仅有助于标引人员进行主题词的选取、数据库的建立以及文献的检索,而且也便于读者高效检索和引用相关学术成果,从而促进学术交流的…...

后盾人JS -- 原型
没有原型的对象 也有没有原型的对象 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document<…...

优选算法的灵动之章:双指针专题(一)
个人主页:手握风云 专栏:算法 目录 一、双指针算法思想 二、算法题精讲 2.1. 查找总价格为目标值的两个商品 2.2. 盛最多水的容器 编辑 2.3. 移动零 2.4. 有效的三角形个数 一、双指针算法思想 双指针算法主要用于处理数组、链表等线性数据结构…...

BUUCTF Pwn axb_2019_brop64 题解
这题是BROP 所以不下文件 先nc一下看看: 先要找到栈溢出长度: from pwn import * import timedef getsize():i 1while True:try:p remote("node5.buuoj.cn", 29367)p.sendafter("Please tell me:", ba * i)time.sleep(0.1)data …...

85.[1] 攻防世界 WEB easyphp
进入靶场 属于代码审计 <?php // 高亮显示当前 PHP 文件的源代码,常用于调试或展示代码 highlight_file(__FILE__);// 初始化两个标志变量,用于后续条件判断 $key1 0; $key2 0;// 从 GET 请求中获取参数 a 和 b $a $_GET[a]; $b $_GET[b];// 检…...

动态规划学习
在进行算法题练习和一些题目中发现关于动态规划的内容较多,觉得有必要系统的学习和练习一下 于是参照bilbilUP主 英雄哪里出来 的动态规划50题和LeetKoke网站进行学习和练习 一 概述 动态规划 是一个有限状态自动机 可以抽象为一个有向无环图 有起始节点 终止节点 …...

数据结构【链栈】
基于 C 实现链表栈:原理、代码与应用 一、引言 栈就是一个容器,可以当场一个盒子,只能一个一个拿,一个一个放,而且是从上面放入。 有序顺序栈操作比较容易【会了链栈之后顺序栈自然明白】,所以我们这里只…...

软件测试02----用例设计方法
今天目标 1.能对穷举场景设计测试点 2.能对限定边界规则设计测试点 3.能对多条件依赖关系进行设计测试点 4.能对项目业务进行设计测试点 一、解决穷举场景 重点:使用等价类划分法 1.1等价类划分法 重点:有效等价和单个无效等价各取1个即可。 步骤&#…...

编程AI深度实战:给vim装上AI
系列文章: 编程AI深度实战:私有模型deep seek r1,必会ollama-CSDN博客 编程AI深度实战:自己的AI,必会LangChain-CSDN博客 编程AI深度实战:给vim装上AI-CSDN博客 编程AI深度实战:火的编程AI&…...

《DeepSeek R1:大模型最简安装秘籍》
DeepSeek R1:AI 大模型界的新起之秀 在人工智能的璀璨星空中,大模型如繁星般闪耀,而 DeepSeek R1 无疑是其中一颗冉冉升起的新星,自问世以来便吸引了全球的目光,在人工智能领域占据了重要的一席之地。 从性能表现上看…...

物业管理平台系统为社区管理带来数字化转型与服务创新新机遇
内容概要 物业管理平台系统是数字化转型的利器,为社区管理带来了许多新机遇。想象一下,传统社区物业管理中繁琐的流程和低效的沟通如何被这种智能系统所替代。通过集成在线收费功能,我们不仅提高了费用收取的准确性,还减少了业主…...

红黑树的封装
一、封装思路 在 STL 中 map set 的底层就是封装了一棵红黑树。 其中连接红黑树和容器的是迭代器,map set 暴露出的接口都不是自己写的,而是红黑树写的,外部接口封装红黑树接口。 所以写出红黑树为 map set 写的接口,再在上层的…...

25.2.3 【洛谷】作为栈的复习不错(学习记录)
今天学习的东西不算多,放了一个星期假,感觉不少东西都没那么清楚,得复习一下才行。今天搞个栈题写,把栈复习一下,明天进入正轨,边复习边学习新东西,应该会有二叉树的学习等等... 【洛谷】P1449 …...

MFC程序设计(七)运行时类信息机制
运行时类信息机制的作用 我们在创建对象时,自己是清楚对象属于哪个类,但是计算机却不清楚。而MFC运行时类信息机制就是解决这个问题而存在的 运行时类信息机制的使用 我们在创建一个类时,只有满足以上三个条件,该类才能支持运行时…...

fflush的概念和使用案例
fflush() 是C语言标准库中用于控制输入/输出缓冲区的函数,其主要功能是强制刷新缓冲区,确保数据及时写入目标设备(如屏幕、文件)。以下是其概念和典型使用场景: 概念 功能: 刷新指定流的缓冲区。对于输出流…...

嵌入式知识点总结 操作系统 专题提升(四)-上下文
针对于嵌入式软件杂乱的知识点总结起来,提供给读者学习复习对下述内容的强化。 目录 1.上下文有哪些?怎么理解? 2.为什么会有上下文这种概念? 3.什么情况下进行用户态到内核态的切换? 4.中断上下文代码中有哪些注意事项? 5.请问线程需要保存哪些…...

React 封装高阶组件 做路由权限控制
React 高阶组件是什么 官方解释∶ 高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。 高阶组件(HOC)就是一个函数&…...

【实践案例】基于大语言模型的海龟汤游戏
文章目录 项目背景提示词构建海龟汤主持人真相判断专家 具体实现流程文心一言大语言模型“海龟汤”插件参考 项目背景 “海龟汤”作为一种聚会类桌游,又称情境推理游戏,是一种猜测情境还原事件真相的智力游戏。其玩法是由出题者提出一个难以理解的事件&…...

NeetCode刷题第20天(2025.2.1)
文章目录 106 Best Time to Buy and Sell Stock with Cooldown 使用 Cooldown 买卖股票的最佳时间107 Coin Change II 换币 II108 Target Sum 目标总和109 Interleaving String 交错字符串110 Edit Distance 编辑距离111 Maximum Subarray 最大子数组112 Jump Game 跳跃游戏113…...

DeepSeek:人工智能领域的革新者与未来展望
在当今这个数据驱动的时代,人工智能(AI)正以前所未有的速度发展,而DeepSeek作为这一领域的先锋,正引领着AI技术的创新与突破。作为一家致力于推动人工智能技术创新与应用的前沿企业,DeepSeek不仅在多语言编…...

Spring Bean 容器
技术成长,是对场景设计细节不断的雕刻! 你觉得自己的技术什么时候得到了快速的提高,是CRUD写的多了以后吗?想都不要想,绝对不可能!CRUD写的再多也只是能满足你作为一个搬砖工具人,敲击少逻辑流…...

Flask代码审计实战
文章目录 Flask代码审计SQL注入命令/代码执行反序列化文件操作XXESSRFXSS其他 审计实战后记reference Flask代码审计 SQL注入 1、正确的使用直白一点就是:使用”逗号”,而不是”百分号” stmt "SELECT * FROM table WHERE id?" connectio…...

springboot启动配置文件-bootstrap.yml常用基本配置
在Spring Boot应用程序中,bootstrap.yml文件通常用于配置应用程序的启动阶段。在这个文件中,你可以配置一些在应用程序启动之前需要加载的属性,例如外部配置源、加密属性等。以下是一些常用的基本配置项: 1. 外部配置源 1.1 配置…...