模版初阶(更新)

文章目录

  • 模版介绍
  • 函数模版
  • 模版匹配规则
  • 类模版
  • 结言

模版介绍

函数模版分为两个类型:

  1. 函数模版
  2. 类模版

函数模版

语法格式: t e m p l a t e < t y p n a m e T 1 , t y p n a m e T 2... > template<typname T1,typname T2...> template<typnameT1,typnameT2...>

void swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}
void swap(double& a, double& b)
{double tmp = a;a = b;b = tmp;
}int main()
{int a = 1, b = 2;double c = 1.1, d = 2.2;cout << a << " " << b << endl;swap(a, b);cout << a << " " << b << endl;cout << "----------------" << endl;cout << c << " " << d << endl;swap(c, d);cout << c << " " << d << endl;return 0;
}

在C语言中,如果我们需要分别交换 i n t int int d o u b l e double double 的数据,那么我们需要定义两个swap函数并且还不能重名。(C语言并不支持函数重载)。

而在C嘎嘎中:

在这里插入图片描述
我们只需要写一个模版就可以了。这里的T在编译的时候会默认替换为我们的 i n t int int d o u b l e double double

在这里插入图片描述
同时通过调试发现,这两个swap都进入我们写的函数模版,那么这两个Swap调用的是同一个函数吗?
在这里插入图片描述
通过反汇编发现,此时我们两个调用的并不是同一个函数。

在这里插入图片描述
当我们使用我们的 S w a p ( ) Swap() Swap()模版的时候,编译器会去默认推演我们此时的参数类型,然后编译器自动生成一个 S w a p ( ) Swap() Swap()函数,中国有句古话:死道友不死贫道[doeg]。咱们只管写一个模版,其他的交给编译器。

在这里插入图片描述
但是如果我们只有一个模版参数的话,传入两个不同类型编译器推导不出来。

此时我们有以下几种方法:
在这里插入图片描述

  1. 添加模版参数
  2. 进行强制类型转化
  3. 直接给定模版参数类型,不让编译器推演

A d d < i n t > Add<int> Add<int> 这个叫做显式实例化。它指定了参数的类型,编译器就不会推演了,T默认会 i n t int int 类型。

模版匹配规则

在这里插入图片描述
在这里插入图片描述

如上图:当我们调用 A d d ( a , b ) Add(a,b) Add(a,b) 的时候,我们写的单参数模版函数其实可以实现的,但是编译器回去默认调用最匹配的 i n t A d d ( i n t l e f t , i n t r i g h t ) int Add(int left, int right) intAdd(intleft,intright)

而当我们调用 A d d ( a , c ) Add(a,c) Add(a,c) 的时候不同参数类型我们的单参数模版函数就不行了,第一张图中我们定义了两个参数的模版参数,所以编译器会去调用我们定义的这个模版函数,而在第二张图中,编译器由于没得选了,只能被迫去调用
i n t A d d ( i n t l e f t , i n t r i g h t ) int Add(int left, int right) intAdd(intleft,intright),只不过会有 精度的丢失。

总结一下:

  • 函数调用会优先调用 (参数匹配+口味好)例如: A d d ( a , b ) Add(a,b) Add(a,b)调用 i n t A d d ( i n t l e f t , i n t r i g h t ) int Add(int left, int right) intAdd(intleft,intright)
  • 当口味不对的时候,会优先调用参数匹配 例如: A d d ( a , c ) Add(a,c) Add(a,c)调用 t e m p l a t e < t y p e n a m e T 1 , t y p e n a m e T 2 > template<typename T1, typename T2> template<typenameT1,typenameT2>
  • 当两个都没有的时候,会将就一样。例如: A d d ( a , c ) Add(a,c) Add(a,c)调用 i n t A d d ( i n t L e f t , i n t R i g h t ) int Add(int Left, int Right) intAdd(intLeft,intRight)

当然模版函数只是单参数的时候,我们传入两个不同类型的参数时,就会报错,编译器不知道推演哪一个?

类模版

typedef int DataType;
class Stack
{
public:Stack(){_array = (DataType*)malloc(sizeof(DataType) * 3);if (NULL == _array){perror("malloc申请空间失败!!!");return;}_capacity = 3;_size = 0;}void Push(DataType data){_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}
private:DataType* _array;int _capacity;int _size;
};

如上述栈,在C语言中,如果我们想要栈中存不同数据。

int main()
{Stack st1; //intStack st2; //doublereturn 0;
}

例如我们想要一个存 i n t int int,一个存 d o u b l e double double,那我们就需要写两个栈了,由于这两个栈的代码都类似,那么在C++中,我们可以定义模版,栈的数据类型,有模版来代替,这样想要存什么类型,直接示例化什么类型的即可。

template<typename T>
class Stack
{
public:Stack(){_array = (T*)malloc(sizeof(T) * 3);if (NULL == _array){perror("malloc申请空间失败!!!");return;}_capacity = 3;_size = 0;}void Push(T data){_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}
private:T* _array;int _capacity;int _size;
};int main()
{Stack<int> st1; //intStack<double> st2; //doublereturn 0;
}

当然我们的模版也可以把声明和定义分开,但是注意: 模版的定义和声明要分离也分离在 .h 文件中,最好不要一个在 .h 文件 一个在 .cpp文件,这样会让编译的时间大大增加。
在这里插入图片描述

在这里插入图片描述
同时我们的T还要另外声明一次,不然编译器不知道T是哪来的。类域声明的时候我们要 S t a c k < i n t > Stack<int> Stack<int>这样写。因为此时我们的 S t a c k < i n t > Stack<int> Stack<int>才是我们的模版类型。

结言

本文只是简单介绍了模版的基本概念,后期学了更深的内容会持续更新…

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

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

相关文章

用这款免费爬虫神器,不用手动撸代码了!

很多人学习Python和我说是为了“爬虫”&#xff0c;爬虫的用处确实很丰富&#xff0c;如&#xff1a; 市场研究&#xff0c;了解竞争对手信息&#xff0c;爬虫收集舆论信息、产品动态。 价格分析&#xff0c;通过抓取不同平台商品价格&#xff0c;监测价格波动&#xff0c;…

【Go系列】 Go语言的入门

为什么要学习Go 从今天起&#xff0c;我们将一同启程探索 Go 语言的奥秘。我会用简单明了的方式&#xff0c;逐一讲解 Go 语言的各个知识点&#xff0c;帮助你从基础做起&#xff0c;一步步深化理解。不论你之前是否有过 Go 语言的接触经验&#xff0c;这个系列文章都将助你收获…

比curl更直观的网站性能测试工具httpstat——筑梦之路

GitHub - davecheney/httpstat: Its like curl -v, with colours. wget https://raw.githubusercontent.com/reorx/httpstat/master/httpstat.pymv httpstat.py /usr/bin/httpstat #移动到环境变量路径chmod x /usr/bin/httpstat #添加可执行权限 exec bash #重置当前bash进…

请编写函数,删除字符串中指定位置下的字符,删除成功函数返回被删字符,否则返回空值

char arr_del(char* p, int pos) {if (pos> strlen(p) || pos<0){printf("这是一个无效下标\n");exit(1);}//到这里就是有效下标char ch p[pos];//把要删除的下标存储for (int i pos; p[i] ! \0; i){p[i] p[i 1];}return ch; } int main() {char arr[100];…

芋道源码 yudao-cloud 文档,视频,开发指南如何看全部

进入官网后可以看到相关内容 但是后端手册开始就看不了了 必须加入知识知识星球才行&#xff0c;很烦 闲**鱼搜索用户 水城打坐的藤壶 找到这个链接 这下大家都懂了吧 现在就可以看到看不到的内容了 在线文档的弹窗可技术去除&#xff0c;很简单 直接起飞哈 包括更新sq…

YOLOv10改进 | 图像去雾 | MB-TaylorFormer改善YOLOv10高分辨率和图像去雾检测(ICCV,全网独家首发)

一、本文介绍 本文给大家带来的改进机制是图像去雾MB-TaylorFormer&#xff0c;其发布于2023年的国际计算机视觉会议&#xff08;ICCV&#xff09;上&#xff0c;可以算是一遍比较权威的图像去雾网络&#xff0c; MB-TaylorFormer是一种为图像去雾设计的多分支高效Transformer…

vim编辑器的使用

vim编辑器&#xff1a; u:撤销操作 ctrlr取消u操作 w&#xff1a;向后按单词移动 b&#xff1a;向前按照单词移动 :%s/printf/cout/g 将printf替换为cout vs copy.c 分屏操作 ctrlww跨屏操作 &#xff01;gcc test.c :!./a.out在vim中对代码进行编译执行 Centos下配置…

嵌入式系统中的加解密签名(2)--- mbedtls认识与使用

笔者来介绍一下mbedtls认识与使用 1、mbedtls认识 mbedtls&#xff08;Embedded TLS&#xff09;&#xff0c;是嵌入式里面实现的TLS协议&#xff0c;用C语言实现。相关的TLS协议以及加密等知识可以看笔者上一篇文章----嵌入式系统中的加解密签名。 基本特点如下图所示&#x…

【自监督学习】DINO in ICCV 2021

一、引言 论文&#xff1a; DINO: Emerging Properties in Self-Supervised Vision Transformers 作者&#xff1a; Facebook AI Research 代码&#xff1a; DINO 特点&#xff1a; 对于一张图片&#xff0c;该方法首先进行全局和局部的裁剪与增强并分别送入教师和学生网络&am…

tesla p100显卡显示资源不足,api调用失败

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

SpringMVC源码分析

文章目录 概要启动阶段请求阶段 概要 以下是调试mvc源码过程中用到的demo以及配置文件 webapp/WEB-INF/web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi"http://…

QImage显示图片像素

在Qt中&#xff0c;QImage 类是用来表示和处理图像的。如果你想查看或显示一个图片的像素数据&#xff0c;你可以使用 QImage 提供的方法来访问这些数据。以下是一些基本的方法来获取和显示图片的像素信息&#xff1a; 获取图像的像素格式&#xff1a; 使用 QImage::format() …

阶段三:项目开发---民航功能模块实现:任务24:航空实时监控

任务描述 内 容&#xff1a;地图展示、飞机飞行轨迹、扇区控制。航空实时监控&#xff0c;是飞机每秒发送坐标&#xff0c;经过终端转换实时发送给塔台&#xff0c;为了飞机位置的精准度&#xff0c;传输位置的密度很大&#xff0c;在地图位置显示不明显。本次为了案例展示效…

Linux基础知识(十六)shell脚本编程

一、简介 用户通过shell向计算机发送指令计算机通过shell给用户返回指令的执行结果 1.1 通过shell编程可以达到的效果 提高工作效率可以实现自动化 1.2 需要学习的内容 Linuxshell的语法规范 1.3 编写shell的流程 第一步&#xff1a;用vi/vim创建一个.sh的文件第二步&am…

位运算在数据库中的运用实践-以MySQL和PG为例

目录 前言 一、两种不同的数据库设计 1、状态字段存储JSON 2、使用位运算 二、数据库中的位运算实践 1、MySQL中的位运算实践 2、PostgreSQL中位运算实践 三、总结 前言 最近在解决某用户的一个业务需求时&#xff0c;遇到一个很有意思的场景。首先先跟大家分享一下需求…

飞腾平台虚拟机组播性能调优指南

【写在前面】 飞腾开发者平台是基于飞腾自身强大的技术基础和开放能力&#xff0c;聚合行业内优秀资源而打造的。该平台覆盖了操作系统、算法、数据库、安全、平台工具、虚拟化、存储、网络、固件等多个前沿技术领域&#xff0c;包含了应用使能套件、软件仓库、软件支持、软件适…

STM32G4 DMA的使用(寄存器开发)

下面以STM32G474为例&#xff0c;使用DMA来存储USART1的接收数据。 1. 查看硬件支持 首先查看要使用的DMA支持的通道数&#xff0c;在手册中有如下说明。 根据上图可以看到&#xff0c;对于不同的设备类型有不同的DMA通道数量。设备类型分类如下图所示。 我使用的是STM32G474…

基于 TI AM62 测试 QtWayland 部署

By Toradex秦海 1). 简介 目前主流的 ARM 平台嵌入式 Linux BSP 的显示后端基本都已经从 X11 升级到了 Wayland&#xff0c; 而常用的 Wayland Compositor - Weston 对于 Linux 下常用的 Qt 图形界面开发框架的一些 Plugin (比如 Qt VirtualKeyboard) 的配合并不完善&#xf…

什么是边缘计算?创造一个更快、更智慧、更互联的世界

前言 如今&#xff0c;数十亿物联网传感器广泛部署在零售商店、城市街道、仓库和医院等各种场所&#xff0c;正在生成大量数据。从这些数据中更快地获得洞察&#xff0c;意味着可以改善服务、简化运营&#xff0c;甚至挽救生命。但要做到这一点&#xff0c;企业需要实时做出决策…

tableau标靶图,甘特图与瀑布图绘制 - 9

标靶图&#xff0c;甘特图与瀑布图 1. 标靶图绘制1.1 筛选器筛选日期1.2 条形图绘制1.3 编辑参考线1.4 设置参考线1.5 设置参考区间1.6 四分位设置1.7 其他标靶图结果显示 2.甘特图绘制2.1 选择列属性2.2 选择列属性2.3 创建新字段2.4 设置天数大小及颜色 3. 瀑布图绘制3.1 she…