初识C++模板

news2024/11/15 8:43:31

文章目录

  • 前言
  • 1.模板概念
  • 2.函数模板
    • 1.示例用法
      • 1. 注意事项
    • 2.函数模板的原理
    • 3.函数模板的实例化
    • 4.模板参数的匹配原则
  • 3.类模板
  • 4.总结

前言

本文主要围c++中的模板进行介绍。模板是c++中一个比较重要的概念,由于模板的存在,c++才能进行泛型编程。模板的存在大大增加了代码的复用性,提升了实际开发效率。


1.模板概念

我们先来看这样一个问题,如何实现一个通用的加法函数呢?没学模板之前,我们知道c++支持函数重载,于是很快写下了这样了代码。

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

使用函数重载虽然可以实现,但是有一下几个不好的地方:1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数。2. 代码的可维护性比较低,一个出错可能所有的重载均出错那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?

如果在C++中,也能够存在这样一个模具,通过给这个模具中填充不同材料(类型),来获得不同材料的铸件(即生成具体类型的代码),那将会节省许多头发。巧的是前人早已将树栽好,我们只需在此乘凉。为了增强代码的复用性,C++中出现了模板,引入了泛型编程的概念。泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。

模板大致分为两种:函数模板与类模板。使用template<typename T1, typename T2,......,typename Tn>表示模板参数列表,注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class

2.函数模板

1.示例用法

以刚才Add函数为例进行模板函数的演示。

在这里插入图片描述

使用template关键字定义模板参数列表,<>中的为模板类型参数 名字可以由自己随便起 但是名字前必须加class 或者typename,以上述代码为例模板参数命名为T,当然也可以指定多个模板参数用逗号分隔即可。有了这个模板参数,不管是double类型还是int类型的数据都可以进行处理,大大增加了代码的复用性。


1. 注意事项

如果想实现模板函数,函数体必须紧跟着模板参数列表。

在这里插入图片描述

图中代码Add和模板参数列表之间隔了一个add函数,编译器就无法识别T.

定义好了模板参数列表一次只能给一个函数使用

在这里插入图片描述

像是这样的代码的就会报错,编译器也不认Swap中的T。

2.函数模板的原理

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。

在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于int类型也是如此

在这里插入图片描述

当我们如图所示调用的时候,就会出现问题。因为编译器无法推演确定这个模板参数T是double还是int,就会出现问题。这点和auto有点像,如果Add函数中其中一个形参是另一种模板参数的话,就不会报错。编译器会前前者推演成 整型 后者推演成 浮点型。


3.函数模板的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。

隐式实例化:让编译器根据实参推演模板参数的实际类型

在这里插入图片描述

如图就是隐式调用模板函数。

显式实例化:在函数名后的<>中指定模板参数的实际类型

在这里插入图片描述

之前我们进行Add(1,2.1)这样的调用的时候编译器会报错。我们可以自己来强制转化数据类型,还可以使用显式实例化。这样就能确定改调用哪个实例化函数了。

在这里插入图片描述

4.模板参数的匹配原则

一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数

在这里插入图片描述

当上述两个函数同时存在的时候,如果进行Add(1,2)调用默认情况下编译器会调用现成的 int Add(int a,int b),因为这个时候有现成符合实参类型的函数可供调用,不用再去实例化函数模板了。当显示调用指定好参数类型时,调用的就是函数模板了。模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

在这里插入图片描述

这个时候毫无疑问调用的是int Add(int a,int b),普通函数支持参数类型自动转换。


3.类模板

类模板定义如下:

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

我以Vector为例演示一下,由于库中已经实现了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();
//其他代码................//
private:
 T* _pData;
 size_t _size;
 size_t _capacity;
 };
// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{
 if(_pData)
 delete[] _pData;
 _size = _capacity = 0;
}

C++中的STL容器都是类模板,这样只用一份代码可以处理不同的数据类型。比如:Vector< int > s1;Vector< double > s2。

要注意一下:类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类.也就是说类模板只能显示实例化,以刚才的Vector为例,Vector类名,Vector< int >才是类型。类模板中函数放在类外进行定义时,需要加模板参数列表

4.总结

本文对模板只是大致介绍下,相当于初步了解模板和泛型编程的概念。关于模板的更高阶的内容后续会进行介绍。以上内容如有问题,欢迎指正!谢谢。

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

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

相关文章

针孔成像模型零基础入门(三)

2020年爆火的Nerf&#xff08;神经辐射场&#xff09;横空出世&#xff0c;据说只要用手机拍照&#xff0c;然后喂给模型&#xff0c;就可以生成3D模型了&#xff0c;我试过了&#xff0c;确有此事&#xff01; 那我们有想过&#xff0c;为什么可以从二维的图片里面获取物体三…

【7】linux命令每日分享——cat查看文件内容

大家好&#xff0c;这里是sdust-vrlab&#xff0c;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;Linux的基本思想有两点&#xff1a;一切都是文件&#xff1b;每个文件都有确定的用途&#xff1b;linux涉及到IT行业的方方面面&#xff0c;在我们日常的学习中&…

Linux网络配置(NAT)

在搭配好一台虚拟机的时候想要下载&#xff0c;安装些什么但一直失败这个时候就可以检查一下网络是否连接这里我们使用centos7举例子使用命令——ifconfig由此可见我们的系统中目前有3个网卡ens33——用于接入外网&#xff0c;该网卡默认关闭lo——用于访问本地网络&#xff0c…

[数据结构]:04-循环队列(数组)(C语言实现)

目录 前言 已完成内容 循环队列实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-QueueCommon.cpp 04-QueueFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容&#xff0c;除其中使用到C引用外&#xff0c;全为C语言代码。使用C引用主要是为了…

1.7校验码:校验码、规则校验码-奇偶校验、检验码-循环校验码CRC、模2除法、校验码-海明校验

1.7校验码&#xff1a;校验码、规则校验码-奇偶校验、检验码-循环校验码CRC、模2除法、校验码-海明校验校验码校验码-奇偶校验编码规则检验码-循环校验码CRC编码规则什么是模2除法如何计算校验码校验码-海明校验校验码 计算机在接收相应信息的时候能够识别的的都是一些电器信号…

【Spring6】| Spring的入门程序、集成Log4j2日志框架

目录 一&#xff1a;Spring的入门程序 1. Spring的下载 2. Spring的jar文件 3. 第一个Spring程序 4. 第一个Spring程序详细剖析 5. Spring6启用Log4j2日志框架 一&#xff1a;Spring的入门程序 1. Spring的下载 官网地址&#xff1a;https://spring.io/ 官网地址&…

数学建模 latex 图片以及表格排版整理(overleaf)

无论是什么比赛&#xff0c;图片和表格的格式都非常重要&#xff0c;这边的重要不只是指规范性&#xff0c;还有抓住评委眼球的能力。 那么怎样抓住评委的眼球&#xff1f; 最重要的一点就是善用图片和表格&#xff08;当然撰写论文最重要的是逻辑&#xff0c;这个是需要长期…

CorelDRAW2023最新版序列号使用教程

CorelDRAW2023用起来非常顺手&#xff0c;旨在为用户解决因在工作上带来的问题&#xff0c;在业内可谓享有极高的声誉&#xff0c;是业内人士常用的一款工具&#xff0c;有了它&#xff0c;可以更好的帮助用户把握好各个方面的细节&#xff0c;减少其他方面的失误&#xff0c;让…

RabbitMQ交换机(Exchanges)

目录 一、概念 二、临时队列 三、绑定 四、Fanout&#xff08;扇出交换机&#xff09; &#xff08;一&#xff09;介绍 &#xff08;二&#xff09;实战 五、Direct&#xff08;直接交换机&#xff09; &#xff08;一&#xff09;介绍 &#xff08;二&#xff09;实…

【LeetCode】1255. 得分最高的单词集合

1255. 得分最高的单词集合 题目描述 你将会得到一份单词表 words&#xff0c;一个字母表 letters &#xff08;可能会有重复字母&#xff09;&#xff0c;以及每个字母对应的得分情况表 score。 请你帮忙计算玩家在单词拼写游戏中所能获得的「最高得分」&#xff1a;能够由 …

我看谁还敢说不懂git

文章目录一、Git介绍1.1、Git的作用1.2、Git的理念1.3、Git的特点1.4、Git对比SVN二、Git的概念2.1、Git基础概念三、Git的基本操作3.1、使用Git管理一个代码仓库的流程3.2、Git常用命令介绍四、Git状态的变化五、Git安装和配置5.1、Git的安装5.2、Git的配置六、Git的高级操作6…

【阅读笔记】SecureML: A System for ScalablePrivacy-Preserving Machine Learning

1. Motivation 针对机器学习中的出现的数据隐私泄露的风险&#xff0c;提出了线性回归、逻辑回归以及简单神经网络的隐私保护模型。 2. Contributions 2.1 为线性回归、逻辑回归以及神经网络设计安全计算协议 2.1.1.1 线性回归 线性回归损失函数为&#xff1a; , 采用SG…

数据分析:某电商优惠卷数据分析

数据分析&#xff1a;某电商优惠卷数据分析 作者&#xff1a;AOAIYI 专栏&#xff1a;python数据分析 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;AOAIYI首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可…

单变量回归问题

单变量回归问题 对于某房价问题&#xff0c;x为房屋大小&#xff0c;h即为预估房价&#xff0c;模型公式为&#xff1a; hθ(x)θ0θ1xh_{\theta}(x)\theta_{0}\theta_{1}x hθ​(x)θ0​θ1​x 要利用训练集拟合该公式&#xff08;主要是计算θ0、θ1\theta_{0}、\theta_{1}θ…

JavaScript DOM和BOM

目录 查找html元素 1.通过id 2.通过标签名 3.通过类名 DOM 1.创建动态的HTML内容 2.修改元素内容 3.改变HTML属性 4.改变css样式 DOM事件 DOM节点 1.添加HTML元素 2.删除HTML元素 浏览器对象 1.Window对象 2.Screen对象 3.History对象 4.Location对象 5.Navi…

深入理解java虚拟机精华总结:jvm内存模型(运行时数据区域)、对象、OOM异常

深入理解java虚拟机精华总结&#xff1a;jvm内存模型、对象、OOM异常jvm内存模型对象对象的创建对象的内存布局对象的访问定位OOM异常Java堆溢出栈溢出方法区溢出直接内存溢出以前读过好几遍《深入理解java虚拟机》这本书&#xff0c;最近又打算重读一遍&#xff0c;并且做一些…

一个接口多个实现如何选择注入对应的Bean_@Primary_@Resource_@Qualifier_@ConditionalOnProperty

文章目录引入结论案例Primary 指定默认注入的BeanQualifier配合Autowired 按名称注入对应的BeanResource 默认按照类型注入&#xff0c;可指定名称注入ConditionalOnProperty 结合配置文件统一设置bean的注入引入 在springboot中&#xff0c;如果一个接口有多个实现&#xff0…

SpringMVC - 13 - SpringMVC执行流程

文章目录1、SpringMVC常用组件2、DispatcherServlet初始化过程a>初始化WebApplicationContextb>创建WebApplicationContextc>DispatcherServlet初始化策略3、DispatcherServlet调用组件处理请求a>processRequest()b>doService()c>doDispatch()d>processDi…

【Neo4j】图数据库CypherQueryLanguage随笔

CQL语言随笔 一、Cyther关系描述 如图&#xff1a;唐僧&#xff0c;孙悟空&#xff0c;白骨精三者的关系图&#xff1a; Cypher语言描述他们的关系&#xff1a; (孙悟空)<-[:赶走]-(唐僧)-[:被骗]->(白骨精)-[:被打死]->(孙悟空) 二、CQL语言的使用案例 创建结点…

七、HTTPTomcatServlet

1&#xff0c;Web概述 1.1 Web和JavaWeb的概念 Web是全球广域网&#xff0c;也称为万维网(www)&#xff0c;能够通过浏览器访问的网站。 在我们日常的生活中&#xff0c;经常会使用浏览器去访问百度、京东、传智官网等这些网站&#xff0c;这些网站统称为Web网站。如下就是通…