C++(10)——模板

目录

    1.什么是泛式编程以及模板的引入:

2. 模板:

2.1 函数模板:

2.2 类模板:


    1.什么是泛式编程以及模板的引入:

      在之前排序的部分中,为了完成某个特定功能,经常会用到交换函数,即:Swap。在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;
}

       这种方法太过复杂,并且,上面三个函数的结构基本一致,不一样的只有每个函数参数的类型。于是,在C++中,便引入了泛式编程,即:编写与类型无关的通用代码,是代码复用的一种手段。来解决上述问题。而对于本篇文章的主题模板,便是泛式编程的基础。

2. 模板:

模板可以分为两类,分别是函数模板和类模板,下面将分开对二者进行介绍:

2.1 函数模板:

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

      对于函数模板的使用,需要借助关键字template来实现,下面将针对于上面的交换函数Swap来介绍关键字的大致使用方法:

template<typename T>void Swap(T& x, T& y)
{int tem = x;x = y;y = tem;
}

       其中,typename是用来定义模板参数关键字,也可以使用class。在定义完模板关键字后,便可以用定义的模板关键字来代替函数中的类型。

      在使用时,直接向函数传递参数即可,例如对于下方的代码:

int main()
{int a = 1;int b = 2;Swap(a, b);cout << a << " " << b << endl;double i = 1.1;double n = 2.2;Swap(i, n);cout << i << " " << n << endl;return 0;
}

运行结果为:

       对于模板如何工作的原理,大致可以认为函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器
      在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。

     对于上述过程,把具体类型的参数传递给函数形参,推断出T的类型的过程称之为模板的推演,把推演后,编写函数的过程称之为模板实例化。

上述模板参数在定义时,只是针对单一类型。假如传递的参数有多个不同的类型,可以通过定义不同的模板参数来解决,例如:

template<typename X, typename Y>
void Cout( X& a, Y& b)
{cout << a << b << endl;}

传递参数如下:

int main()
{int i = 1;double n = 1.1;Cout(i, n);Cout(n, i);return 0;
}

运行结果如下:

当模板参数的数量小于传递参数的类型时,例如:

template<typename A>
A Add(A x, A y)
{return x + y;
}int main()
{int i = 1;double n = 1.1;Add(i, n);return 0;
}

 此时运行代码,编译器会报错。

上述函数模板参数实例化可以称之为隐式实例化,同时,也有显式实例化,方法如下:

template<typename A>
A Add(A x, A y)
{return x + y;
}int main()
{int i = 1;double n = 1.1;cout << Add<int>(i, n) << endl;return 0;
}

此时,double类型的变量n会在使用时被转类型为int,运行上述代码,结果为:

2.2 类模板:

对于下面一个简单的栈:

class Stack
{
public:Stack(int capacity = 4){cout << "Stack( int capacity = 4)" << endl;_a = new int[capacity];_capacity = capacity;_top = _capacity;}~Stack(){cout << "~Stack()" << endl;delete[]_a;_a = nullptr;_top = 0;_capacity = 0;}
private:int* _a;int _top;int _capacity;
};

在之前数据结构的相关文章中,假设需要栈存储不同类型的数据,通常都是利用typedef来完成,即:

typedef int STDataType;class Stack
{
public:Stack(int capacity = 4){cout << "Stack( int capacity = 4)" << endl;_a = new STDataType[capacity];_capacity = capacity;_top = _capacity;}~Stack(){cout << "~Stack()" << endl;delete[]_a;_a = nullptr;_top = 0;_capacity = 0;}
private:STDataType* _a;int _top;int _capacity;
};

但是这种做法同样存在缺点,即只能针对一种单一的类型,如果需要存储两种不同类型的数据,则需要将上述代码进行一次复制,再改写typedef等内容。这样的作法过于麻烦,并且重复性过高。而对于类模板,可以很好的解决问题,方法如下:

template<typename T>class Stack
{
public:Stack(int capacity = 4){cout << "Stack( int capacity = 4)" << endl;_a = new T[capacity];_capacity = capacity;_top = _capacity;}~Stack(){cout << "~Stack()" << endl;delete[]_a;_a = nullptr;_top = 0;_capacity = 0;}
private:T* _a;int _top;int _capacity;
};
int main()
{return 0;
}

在传参时,与函数可以隐式实例化和显式实例化不同,类模板只能显式实例化,例如需要存储int,double两个类型的变量,显式实例化为:

Stack<int> s1;Stack<double> s2;

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

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

相关文章

Jenkins安装和配置

拉取Jenkins镜像 docker pull jenkins/jenkins 编写jenkins_docker.yml version: "3.1" services:jenkins:image: jenkins/jenkinscontainer_name: jenkinsports:- 8080:8080- 50000:50000volumes:- ./data/:/var/jenkins_home/首次启动会因为数据卷data目录没有权限…

强化学习在生成式预训练语言模型中的研究现状简单调研

1. 绪论 本文旨在深入探讨强化学习在生成式预训练语言模型中的应用&#xff0c;特别是在对齐优化、提示词优化和经验记忆增强提示词等方面的具体实践。通过对现有研究的综述&#xff0c;我们将揭示强化学习在提高生成式语言模型性能和人类对话交互的关键作用。虽然这些应用展示…

Django框架完成读者浏览书籍,图书详情页,借阅管理

前情回顾&#xff1a; 使用Django框架实现简单的图书借阅系统——完成图书信息管理 文章目录 1.完成展示图书信息功能1.1django 静态资源管理问题1.2编写图书展示模板HTML 2.完成图书详情页功能2.1从后端获取图书详情信息2.2详情页面展示图书数据 3.完成借阅管理功能3.1管理员…

云卷云舒:AI for DB、DB for AI

云卷云舒&#xff1a;算力网络云原生&#xff08;下&#xff09;&#xff1a;云数据库发展的新篇章-CSDN博客https://blog.csdn.net/bishenghua/article/details/135050556 随着数据库和AI技术的分支同向演进&#xff0c;AI 和数据库间的关联越发紧密了。 大模型的演进发展&a…

MySQL面试题 | 04.精选MySQL面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

py的函数讲解

前言:本章节我们来讲函数&#xff0c;主播略微感觉到有点小难&#xff0c;友友们需要认真看 目录 一.初始函数 1.1关于函数 1.2举例 1.3小结 二.函数的基础语法 2.1关于函数的语法 2.2举例 2.3小结 三.函数的参数 3.1关于函数的参数 3.2举例 3.3小结 四.函数的返回…

Java8常用新特性

目录 简介 1.默认方法 2..Lambda表达式 3.Stream API 4.方法引用 5.Optional类 简介 Java 8是Java编程语言的一个重要版本&#xff0c;引入了许多令人兴奋和强大的新特性。这些特性使得Java程序更加现代化、灵活和高效。让我们一起来探索一些Java 8的常用新特性吧&#…

1.1 计算机网络在信息时代的作用

1.1 计算机网络在信息时代的作用 网络&#xff08;Network&#xff09;由若干结点&#xff08;Node&#xff09;和连接这些结点的链路&#xff08;Link&#xff09;所组成。网络中的结点可以是计算机、集线器、交换机或者路由器等。 图1-1 多个网络还可以通过路由器互连起来&a…

SpringMVC文件上传(CommonsMultipartResolver)

以上传一个图片为例 添加依赖 <!--文件上传--> <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version> </dependency> 配置文件上传解析器 <…

windows下全免费手动搭建php8+mysql8开发环境及可视化工具安装

最近PHP项目少了&#xff0c;一直在研究UE5和Golang&#xff0c;但是考虑到政府、国企未来几年国产化的要求&#xff0c;可能又要重拾PHP。于是近日把用了N年的框架重新更新至适合PHP8.2以上的版本&#xff0c;同时也乘着新装机&#xff0c;再次搭建php和mysql开发环境。本文留…

《产业结构调整指导目录(2024年本)》发布,模糊测试首次纳入

近日&#xff0c;第6次委务会议通过了新版的《产业结构调整指导目录&#xff08;2024年本&#xff09;》&#xff0c;该目录自2024年2月1日起正式实施。 与之前的版本相比&#xff0c;本次目录在行业设置上进行了全面升级&#xff0c;新增了“网络安全”这一重要行业大类&#…

Qt QLineEdit文本框控件

文章目录 1 属性和方法1.1 占位字符串1.2 对齐方式1.3 回显模式1.4 读写控制1.5 格式控制1.6 信号和槽 2 实例2. 布局2.2 代码实现 QLineEdit 是Qt 中的文本框&#xff0c;准确地说是单行文本框&#xff0c;通常用于接受用户的输入。 比如用户输入用户名、密码等&#xff0c;都…

高光谱分类论文解读分享之基于多模态融合Transformer的遥感图像分类方法

IEEE TGRS 2023&#xff1a;基于多模态融合Transformer的遥感图像分类方法 题目 Multimodal Fusion Transformer for Remote Sensing Image Classification 作者 Swalpa Kumar Roy , Student Member, IEEE, Ankur Deria , Danfeng Hong , Senior Member, IEEE, Behnood Ras…

Word·VBA实现邮件合并

目录 制作邮件合并模板VBA实现邮件合并举例 之前写过的一篇使用《python实现word邮件合并》&#xff0c;本文为vba实现方法 制作邮件合并模板 域名可以使用中文&#xff0c;最终完成的word模板&#xff0c;wps操作步骤类似 VBA实现邮件合并 在Excel启用宏的工作表运行以下代…

Linux中断 -- 中断应答、嵌套、

接上文&#xff0c;本文继续介绍Linux软件部分逻辑。 参考内核版本&#xff1a;kernel-4.19 目录 1.中断信号在各级中断控制器中的应答 2.supports_deactivate_key意义 3.中断嵌套 1.中断信号在各级中断控制器中的应答 本章主要从内核软件层面来看各中断控制器对中断信号处…

【python,机器学习,nlp】RNN循环神经网络

RNN(Recurrent Neural Network)&#xff0c;中文称作循环神经网络&#xff0c;它一般以序列数据为输入&#xff0c;通过网络内部的结构设计有效捕捉序列之间的关系特征&#xff0c;一般也是以序列形式进行输出。 因为RNN结构能够很好利用序列之间的关系&#xff0c;因此针对自…

面试算法119:最长连续序列

题目 输入一个无序的整数数组&#xff0c;请计算最长的连续数值序列的长度。例如&#xff0c;输入数组[10&#xff0c;5&#xff0c;9&#xff0c;2&#xff0c;4&#xff0c;3]&#xff0c;则最长的连续数值序列是[2&#xff0c;3&#xff0c;4&#xff0c;5]&#xff0c;因此…

【信息安全】hydra爆破工具的使用方法

hydra简介 hydra又名九头蛇&#xff0c;与burp常规的爆破模块不同&#xff0c;hydra爆破的范围更加广泛&#xff0c;可以爆破远程桌面连接&#xff0c;数据库这类的密码。他在kali系统中自带。 参数说明 -l 指定用户名 -L 指定用户名字典文件 -p 指定密码 -P 指…

Jenkins 问题

从gitlab 仓库拉去代码到Jenkins本地报错 ERROR: Couldn’t find any revision to build. Verify the repository and branch configuration for this job. 问题原因&#xff1a; 创建条目》配置的时候&#xff0c;gitlab仓库不存在master分支 修复后&#xff1a;

x-cmd pkg | czg - git commit 智能生成工具

目录 简介首次用户功能特点竞品和相关作品进一步探索 简介 czg 源于 commitizen/cz-cli 交互插件中 cz-git 的延伸项目&#xff0c;重新使用 TypeScript 编写的零依赖独立的 Node.js 命令行工具。旨在使用交互友好的方式&#xff0c;辅助用户生成规范的 git commit message 约…