【C++】模版:范式编程、函数模板、类模板
目录
一.范式编程
二.函数模板
1.概念与格式
2.原理
3.实例化
4.匹配规则
三.类模板
一.范式编程
在写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;
}
针对不同的类型(int,double,char...)要写相似但不同的函数,如上代码就存在以下问题:
- 重载函数仅仅是类型不同,但只有有新类型出现,就必须增加对应的函数,代码复用率比较低
- 同时代码的可维护性也很低,一个函数出错需要修改,其余的重载也都需要进行修改
为了应对以上问题,模版应运而生。就像活字印刷中的模板一样,根据模板能够印出对应的字,根据颜料的不同,又能印出颜色不同的字,放在C++中也是同理,存在模板这样一个模具,在这个模具中填入不同材料(类型),得到不同的结果,这就是范式编程。
范式编程:编写与类型无关的通用代码,是代码复用的一种手段,模板是范式编程的基础。同时模板又有函数模板和类模板。
二.函数模板
1.概念与格式
函数模板代表了一个函数家族,该函数与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
使用的格式为:
template<class T1,class T2,......>
返回值类型 函数名(参数列表){ 函数主体 }
template就是使用模板的关键字,class可以使用typename替代,但不能使用struct替代,并且class和typename可以混用,可以出现template<class T1,typename T2>的情况,T1,T2...代表不同的类型,可以在函数的实现中使用。
具体到交换函数的函数模板就是这样:
template<typename T>
void Swap(T& left, T& right)
{T temp = left;left = right;right = temp;
}
可以发现,T可以是int,double,char等不同类型,对该模板传入不同的类型,就会得到不同的特定类型函数,这样就大大增加了代码复用率。
小练习:
其中4,6,7是正确声明,尤其注意7这样的class,typename混用是允许的。
2.原理
函数模板本质而言就是一个蓝图,它本身并不是函数。就像类和对象的区别一样,类是图纸,对象才是实际建造起来的房子。函数模板是编译器产生特定类型具体函数的模具,模板只是将本该我们做的重复事情交给了编译器。
在编译器编译阶段,对于模版函数的使用,编译器会根据传入的实参类型来推导生成对应的特定类型的函数,也就是对于不同类型,编译器会根据模板自动生成专门的函数来使用,注意这里调用的函数不是同一个函数。
3.实例化
当使用不同类型的参数来使用函数模板时,就被称为函数模板的实例化。函数模版的实例化分为隐式实例化和显示实例化。
隐式实例化:让编译器根据实参推导模板参数的实际类型
template<class T>
T Add(const T& x, const T& y)
{return x + y;
}int main()
{int a1 = 10, a2 = 20;double d1 = 10.1, d2 = 20.1;//a1,a2都是int类型,因此编译器自动推导模板中T为int类型cout << Add(a1, a2) << endl;//同理,此时推导T为double类型cout << Add(d1, d2) << endl;
}
然而,也会存在编译器无法推导的情况,例如此时,c1和c2类型不相同,c1为int,c2为double,那么此时编译器应该推导T为int还是double呢?编译器不知道,因此报出了错误。
此时可以使用多参数模板解决,就是在template声明模板时,再加一个类型T2,这样就能进行合适的推导了。当然,也可以使用显示实例化:
显示实例化:直接告诉编译器这个类型T是什么,此时哪怕实参不是类型T,也会走隐式类型转换
例如此时若指定T为int类型,那么double类型的c2就会隐式转换为20,double也是同理
4.匹配规则
- 一个非模板函数可以和另外一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数
- 对于非模板函数和同名函数模板,如果其他条件都相同,那么调用时会优先调用非模板函数,从而不会实例化一个模板函数,反之,若模板可以实例化一个更匹配的函数,那么就会选择模板
//非模板函数,适用于int类型相加
int Add(int a, int b)
{return a + b;
}//函数模板,适用于相加
template <class T1, class T2 >
T1 Add(T1 a, T2 b)
{return a + b;
}int main()
{Add(10, 10);//调用非模板Add(10, 10.1);//调用模板return 0;
}
注意:模板函数不允许自动类型转换,但普通函数是可以进行自动类型转换的。
三.类模板
类模板和函数模板类似,格式为:
template<class T1, class T2 ...>
class 类模板名
{
// 类内成员定义
};
例如声明一个简单的Stack栈的类模板:
template <class T>
class Stack
{
public:Stack(int capacity = 4){_arr = new T[capacity];_size = 0;_capacity = capacity;}void Push(const T& data) {if (_size == _capacity){int capacity_s = _capacity * 2;T* tmp = new T[capacity_s];memcpy(tmp, _arr, sizeof(capacity_s));_arr = tmp;_capacity = capacity_s;}_arr[_size++] = data;}private:T* _arr;int _size;int _capacity;
};int main()
{//实例化模板Stack<int> s1;//intStack<double> s2;//doubles1.Push(1);s1.Push(2);s2.Push(2.15);s2.Push(2.16);}
那么这跟直接实现Stack类比较有什么好处呢?在直接实现的stack中,通常使用typedef数据类型来使用,可这也间接限制了栈储存不同类型数据的情况,若同时需要一个存放int类型一个存放double类型的栈,直接实现就很难了,需要单独去实现两个不同类型的stack,而模板就很好的解决了这一问题,直接传入不同的类型来实例化针对不同数据类型的栈:
// Stack是类名,Stack<int>才是类型Stack<int> st1; // int类型的栈Stack<double> st2; // double类型的栈
接下来是一些类模板的练习题,加深对模板的理解:
下面有关C++中为什么用模板类的原因,描述错误的是? ( )
答案:C,模板运行时不检查数据类型,也不保证类型安全,相当于类型的宏替换
下列关于模板的说法正确的是( )
答案:D,对于A而言,前文在隐式类型转换时给出的Add(c1,c2)就是显然的报错,编译器无法自动推导,此时不能省略;对于B而言,类模板重点在后模板二字,是未实例化的模具,而模板类是根据 类模板 这个模具做出的类,是类模板实例化得到的具体类;对于C而言,template<class T, size_t N>这样的存在是允许的,虚拟类型指的是class T,而size_t N并非虚拟类型
下列描述错误的是( )
答案:D,模板类是一个家族,编译器的处理会分别进行两次编译,其处理过程跟普通类不一样
相关文章:
【C++】模版:范式编程、函数模板、类模板
目录 一.范式编程 二.函数模板 1.概念与格式 2.原理 3.实例化 4.匹配规则 三.类模板 一.范式编程 在写C函数重载的时候,可能会写很多同一类的函数,例如交换函数: void Swap(int& left, int& right) {int temp left;left r…...
验证图片旋转
最近在使用百度图片翻译时遇到一个问题,就是图片会翻转90,经与百度沟通,发现是原始图片中有个旋转参数引起的。 于是写个demo验证一下。 // 获取元数据中的旋转方向 func getOrientation() int {//打开图像文件f, err : os.Open("image…...
宏景eHR /ajax/ajaxService SQL注入漏洞复现
0x01 产品简介 宏景eHR人力资源管理软件是一款人力资源管理与数字化应用相融合,满足动态化、协同化、流程化、战略化需求的软件。 0x02 漏洞概述 宏景eHR /ajax/ajaxService 接口处存在SQL注入漏洞,,未经身份验证的远程攻击者通过利用SQL注入漏洞配合数据库xp_cmdshell可…...
从源码看 Redis:深入理解 redisDb 和 redisObject
Redis 是一个广泛使用的内存数据库,以其高性能和丰富的数据结构而闻名。不同于磁盘数据库,磁盘数据库将数据读取到文件中维护,而内存数据库将数据存储在内存中,意味着其想要维护数据,必须在代码中维护一个保存数据的结…...
unity中实现流光效果——世界空间下
Properties{_MainTex ("Texture", 2D) "white" {}_FlowColor ("Flow Color", Color) (1, 1, 1, 1) // 流光颜色_FlowFrequency ("Flow Frequency", Float) 1.0 // 流光频率_FlowSpeed ("Flow Speed", Float) 1.0 // 流光…...
项目经验分享:用4G路由器CPE接海康NVR采用国标GB28181协议TCP被动取流一段时间后设备就掉线了
最近我们在做一个生态化养殖的项目时,发现一个奇怪的现象: 项目现场由于没有有线网络,所以,我们在现场IPC接入到海康NVR之后,再通过一款4G的CPE接入到天翼云的国标GB28181视频平台;我们采用UDP协议播放NVR…...
【RabbitMQ】RabbitMQ不公平分发_预取值
一、不公平分发 1、简介 RabbitMQ中的不公平分发(Unfair Dispatch)是指当多个消费者(Consumers)同时订阅同一个队列(Queue)时,消息的分发机制并非严格平均或公平,而是基于某些条件…...
最新AI模型使用指南和模型
市面上最好的AI大模型 OpenAI GPT-4: 概述:GPT-4 是 OpenAI 发布的最新一代大型语言模型,具备更强的理解和生成自然语言的能力。特点: 强大的文本生成和理解能力。支持多语言处理。可用于各种应用场景,如对话生成、内容…...
数据结构之八大基本排序方法
在数据结构中,排序是一个重要的操作,它有助于提高数据的可读性和可操作性。排序算法有多种,各有优缺点,适用于不同的场景。以下是八大经典排序算法的介绍: 1. 冒泡排序(Bubble Sort) 原理&…...
《Milvus Cloud向量数据库指南》——什么是高可用:深入理解数据库系统中的高可用性架构
什么是高可用:深入理解数据库系统中的高可用性架构 在信息技术日新月异的今天,高可用性(High Availability,简称HA)已成为衡量一个系统,尤其是数据库系统稳定性和可靠性的重要标准。高可用性的核心目标在于确保系统能够持续不断地提供服务,最大限度地减少因维护活动、硬…...
C++ | Leetcode C++题解之第319题灯泡开关
题目: 题解: class Solution { public:int bulbSwitch(int n) {return sqrt(n 0.5);} };...
C# 使用 NLog 输出日志到文件夹
在项目中使用 NuGet 安装 NLog 包以及 NLog.Config 包 配置 nlog.config 在项目的根目录下创建一个 Nlog.config 文件(如果还没有),然后添加如下配置: <?xml version"1.0" encoding"utf-8" ?> <…...
node.js使用NodeMachineID 生成唯一UUID和注意事项
node-machine-id用于获取或生成唯一的机器ID 如何使用 const { machineId, machineIdSync } require(node-machine-id) JSON.stringify(machineIdSync({original: true})) ;方法: machineIdSync 此函数同步获取操作系统本机UUID/GUID,默认情况下进行哈…...
AI大模型在数据治理中的应用
目前,企业的数据治理工作以人工实施为主,其中一些重复性较强的工作,如:数据标准制定和映射、元数据信息完善、数据目录挂载等,需要消耗大量的人力和时间成本,这给本来就难以量化业务价值的治理工作的顺利推…...
【初学人工智能原理】【12】循环:序列依赖问题
前言 本文教程均来自b站【小白也能听懂的人工智能原理】,感兴趣的可自行到b站观看。 代码及工具箱 本专栏的代码和工具函数已经上传到GitHub:1571859588/xiaobai_AI: 零基础入门人工智能 (github.com),可以找到对应课程的代码 正文 对于…...
【QT】无法打开QT的ui文件,出现闪退情况
打开qt的ui文件出现闪退的情况: 解决办法:点击扩展-Qt VS Tools-Options 找到Qt General中的Qt Designer 的Run in detached window改为True。...
三、Spring-WebFlux实战案例-流式
目录 一、springboot之间通讯方式 1. 服务端 (Spring Boot) 1.1 添加依赖 1.2 控制器 2. 客户端 (WebClient) 2.1 添加依赖 2.2 客户端代码 3. 运行 二、web与服务之间通讯方式 1、服务端代码 2、客户端代码 3、注意事项 三、移动端与服务端之间通讯方式…...
html+css 实现hover双层按钮
前言:哈喽,大家好,今天给大家分享htmlcss 绚丽效果!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 文…...
SPIFFS与LittleFS的对gz文件格式的区别
SPIFFS 只能安装在Arduino上。LittleFS支持Arduino IDE和VScode的 PlatformIO。 SPIFFS serveStatic: server.serveStatic("/", SPIFFS, "/") 负责提供 SPIFFS 文件系统中的文件。您可以在 SPIFFS 上放置 .gz 文件,并该方法将自动处理它们。 …...
STM32L051K8U6-开发资料
STM32L051测试 (四、Flash和EEPROM的读写)-云社区-华为云 (huaweicloud.com) STM32L051测试 (四、Flash和EEPROM的读写) - 掘金 (juejin.cn) STM32L0 系列 EEPROM 读写,程序卡死?_stm32l0片内eeprom_stm3…...
Markdown语法学习
Markdown学习 一、基础语法讲解 1. 换行 本行末尾双空格然后回车(在Typora的中直接回车也可以) 2. 换段 本段末尾两次回车 3. 加粗 **加粗** __加粗__效果:加粗 4. 斜体 *加粗* _加粗_效果:斜体 5. 斜体加粗 ***加粗**…...
[最短路Floyd],启动!!!
B3647 【模板】Floyd #include<bits/stdc.h> #define ll long long #define fi first #define se second #define pb push_back #define PII pair<int,int > #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; const int N …...
7月29(信息差)
🌍最强模型 Llama 3.1 如期而至!扎克伯格最新访谈:Llama 会成为 AI 界的 Linux 🎄谷歌AlphaProof攻克国际奥赛数学题 https://www.51cto.com/article/793632.html ✨SearchGPT第一波评测来了!响应速度超快还没广告&…...
ubuntu中禁止使用鼠标拖动来移动文件
windows和ubuntu中都可以拖动文件到其他路径,然后达到移动文件的目的。 这种方式有好处也有坏处,好处是移动文件方便了,坏处是误操作后会造成故障,尤其是ubuntu中,本身鼠标就特别灵敏并且操作不便,拖动一个…...
【密码学】椭圆曲线密码体制(ECC)
椭圆曲线密码体制(Elliptic Curve Cryptography, ECC)是一种基于椭圆曲线数学特性的公钥密码系统。在介绍椭圆曲线之前,我们先来了解一下椭圆曲线的基本概念。 一、椭圆曲线是什么? (1)椭圆曲线的数学定义…...
第25集《大佛顶首楞严经》
丑二、腾疑细释 分二:寅一、阿难腾疑;寅二、如来细释 请大家打开讲义第五十六页,“丑二、腾疑细释”。 本经的修学重点,就是修学首楞严王三昧。它的整个重点,其实就是一个心地法门。我们在行菩萨道的时候慢慢会发觉…...
python 读写文件之 open 和 with open() 详细解析
python 读写文件之 open 和 with open() 详细解析 文章目录 python 读写文件之 open 和 with open() 详细解析1. open() 和 with open() 能打开不同的文件类型吗?2. 文本文件和二进制文件的区别2.1 文本文件 (Text Files)2.2 二进制文件 (Binary Files)区别 3. 读文…...
操作系统:内存----知识点
什么是虚拟内存? 虚拟内存简称虚存,是计算机系统内存管理的一种技术。它是相对于物理内存而言的,可以理解为“假的”内存。它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),允许程序员编…...
pfx如何配置到nginx中
有pfx文件的时候如何在nginx上使用 好的,如果您已经确认没有中间证书(或中间证书内容为空),那么可以直接使用服务器证书和私钥。以下是简化后的步骤: 从PFX文件中导出私钥: openssl pkcs12 -in xxx.com.pfx…...
详细测评下搬瓦工香港CN2 GIA VPS
搬瓦工香港VPS分移动CMI和电信CN2 GIA两个大类,一个属于骨干网,一个属于轻负载。搬瓦工的香港CN2 GIA根据测试来看实际上是CN2 GIABGP,并非三网纯CN2 GIA。详细测评数据如下: 用FIO再给测试一下硬盘I/O,可以仔细看看数…...
网站建设流程图解/北京网站优化方式
文章目录杨辉三角形例题第一题第二题第三题第四题杨辉三角形 前提:每行端点与结尾的数为1。 每个数等于它上方两数之和。 每行数字左右对称,由 1 开始逐渐变大。 第 n 行的数字有 n 项。 前 n 行共[(1 n) * n] / 2 个数。 第 n 行的 m 个数可表示为…...
公示专家的定义/网络优化工程师前景如何
小编典典这是允许您使用基于Java的Spring配置在服务器模式下启动H2数据库的代码:private static final String H2_JDBC_URL_TEMPLATE "jdbc:h2:%s/target/db/sample;AUTO_SERVERTRUE";Value("classpath:seed-data.sql")private Resource H2_SC…...
1920的做网站做多大/目前疫情最新情况
文章目录 1. Collection体系下线程安全集合2. CopyOnWriteArrayList类(线程安全的List)3. CopyOnWriteArraySet类(线程安全的Set)4. ConcurrentHashMap类(线程安全的Map)补充:对ConcurrentHashMap的线程安全算法理解1. Collection体系下线程安全集合 Collection体系集合…...
建设工程信息网站有哪些/手机百度2020
这算是小菜第一篇有关技术的博客,这篇博客不是说WPF binding,只是本小菜的一个想法 ,好了 直接正文吧 对于一般的WPF绑定,需要有一个Class来描述对象的基本属性,如下 public class SimpleModel { public string Versio…...
微信网站开发怎么做/seo咨询常德
打从回到老家,平时没事儿就写写blog,看看访问量和排名,也算有点小成就感。 可是CSDN最近啥时候更新排名貌似时间上有点不准,以前的时候大概8点半左右就更新了,可是最近好像有点延迟。 可不可以做个监控呢?…...
电商网站页面设计/免费html网站制作成品
环境:Springboot2.4.11 通常,当需要实现通用类型转换逻辑时,可以使用转换器SPI 例如,用于在java.util.Date和Long之间转换。当你在客户端环境(如web应用程序)中工作并且需要解析和打印本地化字段值时&…...