C++:模板(函数模板,类模板)

目录

泛型编程

函数模板

函数模板格式

函数模板的原理

函数模板的实例化

类模板

类模板格式

类模板实例化


模板分为函数模板和类模板

在C++中使用模板可以让我们实现泛型编程

泛型编程

如果我们需要实现一个加法add函数,那么会怎么实现呢?

int Add(int a, int b)
{return a + b;
}

 上面就是一种实现方法

但是它有严重的缺点,就是它的返回值和形参都是固定的,都是整型

如果我们还要写浮点型,那么我们还得多写一个函数

int Add(int a, int b)
{return a + b;
}double Add(double a, double b)
{return a + b;
}

但是在C++中我们有模板,我们可以理解为这个Add函数就是模具,我们给它什么材料它就是什么材料 

所以如果是C++我们可以这样写

template<class T>
T Add(T a, T b)
{return a + b;
}

这就是函数模板 

函数模板

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

函数模板格式

上面的加法的模板就是一种简单的格式

template<class T>
T Add(T a, T b)
{return a + b;
}

首先要有template这个关键字, 后面跟上<>里面的class也是一个关键字,T就是一个类似于类型的东西,我们实例化出来的其他内置类型最后就会把这个T替换掉

这是比较常用的一种写法

当然我们也可以把class换成typename

template<typename T>
T Add(T a, T b)
{return a + b;
}

这两种写法效果都一样

也可以写多个模板

template<class T1, class T2, ..., class Tn>
void Add(T1 a, T2 b, ..., Tn n)
{//...
}

函数模板的原理

在编译的时候,如果我们在一个main函数里既写了整型的Add又写了浮点型的Add,那么这是两个函数还是一个函数呢?

答案是两个函数

相当于编译器帮我们写了两个函数,只是单纯的把模板T给推演成了其他的内置类型,如下图

 所以模板就相当于编译器帮我们做了我们原本要做的事情

当然了上面的Add函数其实写的都不是很好,我们不改变a和b的话可以加上const修饰,还可以加上引用减少拷贝,提高效率

template<class T>
T Add(const T& a, const T& b)
{return a + b;
}

函数模板的实例化

如果类型不匹配是会报错的 

template<class T>
T Add(const T& a, const T& b)
{return a + b;
}int main()
{int a = 10;double d = 10.0;Add(a, d);return 0;
}

 

这里就是因为a和d的类型不一致导致报错

编译器识别出a是int类型,到模板里那个T就是int,但是后面的d是double,跟int匹配不上,所以自然就报错了 

解决方案 

template<class T>
T Add(const T& a, const T& b)
{return a + b;
}int main()
{int a = 10;double d = 10.0;Add(a, (int)d);return 0;
}

可以像上面把d强转成int类型即可 

template<class T>
T Add(const T& a, const T& b)
{return a + b;
}int main()
{int a = 10;double d = 10.0;Add((double)a, d);return 0;
}

或者是把a强转成double类型

template<class T>
T Add(const T& a, const T& b)
{return a + b;
}int main()
{int a = 10;double d = 10.0;Add<int>(a, d);return 0;
}

也可以在函数名后面加上<类型>,相当于是告诉了编译器我要实例化一个int类型的Add,这样即使d的类型不匹配,进入函数后也会隐式类型转换成int

template<class T>
T Add(const T& a, const T& b)
{return a + b;
}int main()
{int a = 10;double d = 10.0;Add<double>(a, d);return 0;
}

当然double也没问题,和前面的int原理一致  

类模板

之所以叫类模板就是在类中使用模板,

类模板格式

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

也就是在一个类中,我们可以使用多个类型

template<class T>
class Stack
{
public:Stack(size_t capacity = 4){_array = new T[capacity];_capacity = capacity;_size = 0;}void Push(const T& data);
private:T* _array;size_t _capacity;size_t _size;
};

也就是说,例如我们写一个栈, 写了一个栈的模板出来,就相当于把所有内置类型的栈都写了出来,我们在函数内部想定义什么类型的栈就定义什么类型的栈,这是C语言办不到的

int main()
{Stack<int> st1;Stack<double> st2;return 0;
}

类模板实例化

上面的代码就是一个实例化

我们实例化出了一个int类型的栈和double类型的栈

因为我们使用一个类的时候不像函数一样可以传参从而让编译器缺定我们模板的类型是什么

所以我们在实例化一个类的时候需要加上<类型>来让编译器知道我们需要什么类型的模板,从而给我们实例化出来,就像上面函数模板中的a和d一样


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

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

相关文章

python 闭包、装饰器

一、闭包&#xff1a; 1. 外部函数嵌套内部函数 2. 外部函数返回内部函数 3.内部函数可以访问外部函数局部变量 闭包&#xff08;Closure&#xff09;是指在一个函数内部定义的函数&#xff0c;并且内部函数可以访问外部函数的局部变量&#xff0c;即使外部函数已经执行…

重磅 - Github 上免费大屏来啦,教你快速搭建积木报表

先看看大屏效果 JimuReport积木报表的集成版本&#xff0c;已经提供了免费数据可视化设计工具。 支持丰富的数据源连接&#xff0c;能够通过拖拉拽方式快速制作图表和门户设计&#xff1b;目前支持多种图表类型&#xff1a;柱形图、折线图、散点图、饼图、环形图、面积图、漏斗…

# Redis 入门到精通(七)-- redis 删除策略

Redis 入门到精通&#xff08;七&#xff09;-- redis 删除策略 一、redis 删除策略–过期数据的概念 1、Redis 中的数据特征 Redis 是一种内存级数据库&#xff0c;所有数据均存放在内存中&#xff0c;内存中的数据可以通过TTL指令获取其状态。 XX &#xff1a;具有时效性…

Linux下git入门操作

0.创建仓库 可以按这个配置来&#xff0c;.gitignore中存放了上传时忽略的文件类型后缀。 1.clone仓库 在gitee上创建好仓库&#xff0c;点击克隆/下载&#xff0c; 复制地址fyehong/Linux_notes 。 在所需的文件夹中放置仓库。比如我在文件夹lesson9下存储仓库。就在less…

C# 与C++ cli

cli CLI&#xff08;Command Line Interface&#xff09;是一种通过命令行界面与计算机系统进行交互的方式。它提供了一种以文本形式输入命令和接收系统输出的方法&#xff0c;用于执行各种操作和管理计算机系统。以下是CLI的详细解释&#xff1a; 一、定义与基本概念 定义&…

Python酷库之旅-第三方库Pandas(041)

目录 一、用法精讲 136、pandas.Series.ne方法 136-1、语法 136-2、参数 136-3、功能 136-4、返回值 136-5、说明 136-6、用法 136-6-1、数据准备 136-6-2、代码示例 136-6-3、结果输出 137、pandas.Series.eq方法 137-1、语法 137-2、参数 137-3、功能 137-4、…

医疗信息化之PACS系统源码,C#医学影像系统源码,成熟在用稳定运中

C#语言开发的一套PACS系统源码&#xff0c;C/S架构&#xff0c;成熟稳定&#xff0c;多家大型综合医院应用案例。自主版权&#xff0c;支持二次开发&#xff0c;授权后可商用。 医学影像存储与传输系统是针对数据库存储、传输服务、图像处理进行了优化,存储更安全、传输更稳定、…

Ethernet/IP转CC-Link IEFB协议转化网关(通讯解决方案)

怎么样把Ethernet/IP和CC-Link IEFB网络通讯连接起来呢?最近有很多朋友咨询这个问题&#xff0c;在这里统一为大家详细说明一下。其实有一个设备可以很轻松地解决这个问题&#xff0c;名为YC-EIP-TCP&#xff0c;下面是详细信息。 一&#xff0c;设备主要功能 1、YC-EIP-CCL…

ios 15-16手机绕过ssl验证(抓取app上的https包)

绕过ssl验证的基本流程 前提概要&#xff1a;为什么你的charles抓不了https包 ios 越狱ios rootful安装ios 越狱商店sileo安装substitute越狱商店安装SSL Kill Switch3 全流程坑点巨多&#xff0c;博主亲身踩坑&#xff0c;务必按着步骤来 准备工作 type b to c 的数据线苹果…

【ffmpeg命令入门】实现画中画

文章目录 前言画中画是什么画中画的外观描述效果展示为什么要用画中画应用场景示例 使用FFmpeg添加画中画示例命令参数解释调整嵌入视频的位置调整嵌入视频的大小处理音频 总结 前言 FFmpeg 是一款强大的多媒体处理工具&#xff0c;广泛用于音视频的录制、转换和流处理。它不仅…

Dockerfile制作部署wordpress-6.6

目录 一. 环境准备 二. 准备对应的配置文件 三. 编写Dockerfile 四. 构建镜像 五. 配置MySQL 六. 安装wordpress 七. 扩展 一. 环境准备 localhost192.168.226.25 rocky_linux9.4 Docker version 27.0.3 关闭防火墙和selinux&#xff0c;进行时间同步。 安装docker…

IDEA打开终端报错Cannot open Local Terminal命令行功能

idea项目中不能打开命令行功能 IDEA打开终端报错Cannot open Local Terminal 意思是打开命令行发生错误 idea上配置shell终端&#xff0c;命令行页面 打开右上角 File–> setting–> Tools–> 终端 找到Shell 路径 文本框中原本是是powershell.exe&#xff0c;现在…

SpringSecurity如何正确的设置白名单

在SpringSecurity中,往往需要对部分接口白名单访问,而大部分在使用Security中就有一个误区,那就是免鉴权访问和白名单的区别。 大部分的Security文章包括官方文档给出免鉴权访问都是使用.permitAll()去对相应路径进行免鉴权访问,但实际上这仅仅只表示该资源不需要相应的权限访问…

【云原生】Kubernetes 中的 PV 和 PVC 介绍、原理、用法及实战案例分析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

FPGA与ASIC:深入解析芯片设计的双子星

前言 在半导体世界里&#xff0c;FPGA&#xff08;Field-Programmable Gate Array&#xff0c;现场可编程门阵列&#xff09;与ASIC&#xff08;Application-Specific Integrated Circuit&#xff0c;专用集成电路&#xff09;是两种截然不同的芯片设计策略&#xff0c;各自在…

Facebook的创新之路:科技驱动的社交革命

Facebook自2004年创立以来&#xff0c;已经从一个大学校园内的社交网站发展成为全球最大的社交媒体平台。其成功的背后&#xff0c;不仅仅是广泛的用户基础和高效的运营模式&#xff0c;更在于其不断推进的技术创新。本文将探讨Facebook在技术创新方面的诸多努力&#xff0c;如…

C#入门与精通

C#精通 本文章主要是对于学习C#基础难点进行学习以及与java语言的不同点&#xff0c;详细学习可见官网&#xff1a;https://dotnet.microsoft.com/en-us/learn 文章目录 C#精通VSVS基本设置 C#是什么C#程序控制台输出变量内插占位符C#foreach循环类型转换操作数组内置方法格式设…

Python爬虫(5) --爬取网页视频

文章目录 爬虫爬取视频指定url发送请求UA伪装请求页面 获取想要的数据解析定位定位音视频位置 存放视频完整代码实现总结 爬虫 Python 爬虫是一种自动化工具&#xff0c;用于从互联网上抓取网页数据并提取有用的信息。Python 因其简洁的语法和丰富的库支持&#xff08;如 requ…

数据结构--二叉树详解

一&#xff0c;概念 1&#xff0c;结点的度&#xff1a;一个结点含有子树的个数称为该结点的度 2&#xff0c; 树的度&#xff1a;一棵树中&#xff0c;所有结点度的最大值称为树的度&#xff1b; 3&#xff0c;叶子结点或终端结点&#xff1a;度为0的结点称为叶结点&#x…

go语言Gin框架的学习路线(十一)

目录 GORM的CRUD教程 更新操作 更新所有字段 更新指定字段 使用 Select 和 Omit 更新 无 Hooks 更新 批量更新 删除操作 删除记录 批量删除 软删除 物理删除 示例代码 GORM的CRUD教程 CRUD 是 "Create, Read, Update, Delete"&#xff08;创建、查询、…