C++_模板

       

目录

1、函数模板

1.2 模板原理

2、多个模板参数

3、模板的显示实例化

4、模板的匹配

5、类模板

结语:


前言:

        在C++中,模板分为函数模板和类模板,而模板的作用就是避免了重复的工作,把原本是程序员要做的重复工作交给了编译器去做。比如实现两个变量的交换函数,如果这两个变量是int类型则需要写一个int类型的交换函数,若是double类型则要再写一个double类型的交换函数,这样一来增加了很多反复的工作,若用函数模板就能解决以上问题,只需要写一个交换函数的模板,不管是什么类型,都可以通过该模板实现两个变量的交换。

1、函数模板

        用交换函数举例子,如果要交换三种类型的数据则需要三个交换函数构造重载,写起来很冗杂而且可读性较差:

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;
}

        以上三个交换函数可以用一个函数模板代替,模板的格式如下:

template<class T1, class T2,......,class Tn>
//template是关键字,用于定义一个模板
//class替换成typyname也可以实现模板
//T1和T2是模板的关键部分,表示模板类型,可以接收任意的实参类型
//T1和T2也理解为模板参数

        有了模板的格式,就可以写一个交换函数的模板,同时测试交换各种不同的数据类型,观察利用函数模板是否可以实现交换。测试代码如下:

#include<iostream>
using namespace std;template<class T>//写在函数上面实现函数模板
void Swap(T& t1, T& t2)//Swap为函数模板名
{T temp = t1;t1 = t2;t2 = temp;
}int main()
{int a = 2, b = 3;double a1 = 2.2, b1 = 3.3;char a2 = 'a', b2 = 'b';Swap(a, b);Swap(a1, b1);Swap(a2, b2);cout << a << " " << b << endl;cout << a1 << " " << b1 << endl;cout << a2 << " " << b2 << endl;return 0;
}

        运行结果:


        这里要说明一点,模板的格式只对在他下面的第一个对象(即函数)有效,模板下面的第二个函数不是模板函数,比如:

1.2 模板原理

        模板表面上减少了很多重复的工作,实际上是把原本由程序员进行的重复工作交给了编译器完成,在底层,编译器还是会根据不同的类型去生成该类型的交换函数。

2、多个模板参数

        上述的模板参数只有一个,即:T。因为交换函数一般交换的两个变量类型都是相同的,因此一个模板参数就足够了,但是很多情况下函数要处理的数据类型不止一个,这时候该类情况的函数模板就需要多个模板参数了。

        多个模板参数写法如下:

#include<iostream>
using namespace std;template<class T1, class T2>//两个模板参数T1和T2
T1 func(T1& t1, T2& t2)//注意返回类型的选取
{return t1 + t2;
}int main()
{int a = 2;double b = 2.2;cout << func(a, b) << endl;
}

        运行结果:

        如果模板涉及到返回类型,则要注意返回类型的选取。 

3、模板的显示实例化

        以上模板参数的具体类型都是自动的根据实参类型而定的,把这种自动识别类型的方式叫做隐式实例化,除了隐式实例化识别模板参数类型,还可以手动指定模板参数类型,即在调用模板函数时,在函数名后面加上'<>',并且在‘<>’中写上指定的类型。

        如果只有一个模板参数是无法处理实参传递两个不同类型变量的情况,解决方法有两种:1、采用多个模板参数,2、使用显示实例化模板。

        显示实例化示例代码如下:

#include<iostream>
using namespace std;template <class T>
T Add(const T& t1,const T& t2)
{return t1 + t2;
}int main()
{int a = 2, b = 3;double a1 = 2.2, b1 = 3.3;//b1是double类型,a是int类型,而模板参数只有一个T,不能够直接的将a、b作为实参传递//因此可以手动指定模板参数T的类型为int,即显示实例化cout << Add<int>(a, b1) << endl;cout << Add<double>(a1, b) << endl;//double类型同理return 0;
}

        运行结果:

4、模板的匹配

        如果存在一个函数模板和一个非模板且同名的函数,调用时实参类型若与非模板且同名的函数的类型对应上,则直接调用非模板且同名的函数。若调用时实参类型必须要经过函数模板才能生成该类型的函数,则调用函数模板。总而言之就是编译器会自动调用“当下最匹配”的函数

        示例代码如下:

#include<iostream>
using namespace std;template <class T>
T Add(T t1, T t2)
{return t1 + t2;
}int Add(int x, int y)
{return x + y;
}int main()
{int a = 2, b = 3;Add(a, b);//此处调用int返回类型的AddAdd<int>(a, b);//若用显示调用则强制调用函数模板Adddouble a1 = 2.2, b1 = 3.3;Add(a1,b1);//只能通过调用模板函数Add来实现double类型的和Add(2, 2.2);//一个int类型,一个double类型,显然一个模板参数不够,因此会调用int类型Addreturn 0;
}

        示意图:

5、类模板

        之前通常都是用typedef进行类型的重命名,虽然该方法可以解决一部分问题,但是如果想让一个类实例化出两个不同类型的对象那么typedef就做不到了,只能通过显示实例化类模板,才能实现一个类可以实例化出两个不同类型的对象。

        类模板的格式跟函数模板相似,只不过把函数替换成了类:

template<class T1, class T2,......,class Tn>
class A//A表示类模板名
{}

        示例代码如下:

#include<iostream>
using namespace std;template<class T>
class Stack//Stack不再是具体的某一个类,而是一个类模板
{
public:Stack(int capacity=4)//构造函数初始化:_arr(new T[capacity])//可以申请不同类型的空间,_top(0),_capacity(capacity){}void push(const T& x)//压栈{_arr[_top++] = x;}T& operator[](int i)//显示栈里元素{return _arr[i];}private:T* _arr;//_arr可以转变不同类型的指针size_t _top;size_t _capacity;
};int main()
{Stack<int> sti;//Stack不再是类型,Stack<int>才是类型。Stack<double> std;//同理Stack<double>才是一个类型//可以同时实现两个数据类型的Stacksti.push(6);std.push(6.6);cout << sti[0] << endl;cout << std[0] << endl;return 0;
}

        运行结果:

        这里要注意的是:如果要通过类模板进行实例化对象,那么必须在类模板名的后面加上'<>',并且在‘<>’中表示类型,才能用类模板实例化对象。可以理解为类模板不是一个真正的类,而类模板+'<type>'才是一个真正的类。 

结语:

        以上就是关于C++模板的讲解,模板的出现减轻了程序员的工作,并且提供了代码的可读性和可维护性。最后希望本文可以给你带来更多的收获,如果本文对你起到了帮助,希望可以动动小指头帮忙点赞👍+关注😎+收藏👌!如果有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!!

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

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

相关文章

Element|InfiniteScroll 无限滚动组件的具体使用方法

目录 InfiniteScroll 无限滚动 基本用法 详细说明 v-infinite-scroll 指令 infinite-scroll-disabled 属性 infinite-scroll-distance 属性 总结 需求背景 &#xff1a; 项目统计管理列表页面&#xff0c;数据量过多时在 IE 浏览器上面会加载异常缓慢&#xff0c;导致刚…

A股贵如金?Python量化验证AH股溢价效应,跟着买15年18倍?

2023年9月15日&#xff0c;A股中国人寿的收盘价为35.64元人民币&#xff0c;同一天港股的价格却仅为12.1元港币&#xff0c;折合人民币11.1元&#xff0c;两者相去甚远。 但深究后会发现&#xff0c;两个股票代表的是同一家公司。 中国人寿在香港和上海都发行了股票&#xff0…

【AI】LoFTR图像匹配算法源码解析

0.LoFTR简介 Local Feature Transformers &#xff08;LoFTR&#xff09;是一种Detector-free的局部特征匹配方法&#xff0c;使用了具有自注意层和互注意层的Transformer模块来处理从卷积网络中提取的密集局部特征&#xff1a;首先在低特征分辨率&#xff08;图像维度的1/8&a…

python使用selenium操作浏览器的教程

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 重复的操作令手工测试苦不堪言&#xff0c;于是自动化测试出现了&#xff01; 作为web应用里最出名的自动化测试工具&#xff0c;selenium让web应用的测试轻松了…

Unity之地形的构建

PS&#xff1a;公司没活干&#xff0c;好无聊偷偷摸鱼学Unity&#xff0c;害怕自己学完之后忘记&#xff0c;写下这一篇博客 先来看一下效果图&#xff1a;有山有水有树有草地 创建一个新的Unity3D项目 这里要用到Unity官方的免费资源包&#xff08;现在好像已经下架了百度网盘…

芯课堂 | LVGL基础知识(二)

引言 在 LVGL 中&#xff0c;用户界面的基本构建块是对象&#xff0c;也称为小部件(widget)。默认情况下&#xff0c;LVGL在背景上绘制旧对象&#xff0c;在前景上绘制新对象。 对象层级(Layers) 创建对象层级顺序 默认情况下&#xff0c;LVGL在背景上绘制旧对象&#xff0c…

redis重启后数据丢失问题解决(亲测好用)

redis修改密码重启后发现redis中的数据丢失了 解决办法&#xff1a; 首先在redis的安装目录下查找重启之前的dump.rdb文件&#xff0c;发现只有当天的一个dump.rdb文件&#xff0c;确认不是重启备份的文件 然后我就全盘找一下dump.rdb的备份文件&#xff0c;找到前一天的备份…

机器学习中的监督学习基本算法-逻辑回归简单介绍

逻辑回归 逻辑回归&#xff08;Logistic Regression&#xff09;是一种用于解决二分类问题的统计学习方法&#xff0c;尽管名字中带有"回归"一词&#xff0c;但实际上它是一种分类算法。逻辑回归的主要目标是通过学习从输入特征到一个离散的输出&#xff08;通常是0…

前端技术-调试工具(上)

页面制作之调试工具 常用的调试工具有Chrome浏览器的调试工具&#xff0c;火狐浏览器的Firebug插件调试工具&#xff0c;IE的开发人员工具等。它们的功能与使用方法大致相似。Chrome浏览器简洁快速&#xff0c;功能强大这里主要介绍Chrome浏览器的调试工具。 打开 Google Chrom…

【BIAI】Lecture2-Visual system

Lecture 2 - Visual System 专业术语 central nervous system(CNS) 中枢神经系统 pupil 瞳孔 iris 虹膜 cornea 角膜 retina 视网膜 fovea 中央凹 或 黄斑区 kens 晶状体 optic nerve 视神经 Bipolar cells 双极细胞 Ganglion cells 神经节细胞 rods 杆状细胞 cones 锥状细胞 …

视频格式网络地址转换视频到本地,获取封面、时长,其他格式转换成mp4

使用ffmpeg软件转换网络视频&#xff0c;先从官网下载对应操作系统环境的包 注意:网络地址需要是视频格式结尾&#xff0c;例如.mp4,.flv 等 官网地址&#xff1a;Download FFmpeg window包&#xff1a; linux包&#xff1a; 如果下载缓慢&#xff0c;下载迅雷安装使用…

imgaug库指南(一):从入门到精通的【图像增强】之旅

文章目录 引言imgaug简介安装和导入imgaug代码示例imgaug的强大之处和用途小结结尾 引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和…

清风数学建模笔记-多分类-fisher线性判别分析

内容&#xff1a;Fisher线性判别分析 一.介绍&#xff1a; 1.给定的训练姐&#xff0c;设法投影到一维的直线上&#xff0c;使得同类样例的投影点尽可能接近和密集&#xff0c;异类投影点尽可能远离。 2.如何同类尽可能接近&#xff1a;方差越小 3.如何异类尽可能远离&#…

AI:111-基于深度学习的工业设备状态监测

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

122基于matlab的CSO-SVM,BA-SVM模式识别模型

基于matlab的CSO-SVM&#xff0c;BA-SVM模式识别模型。优化SVM的两个参数晚上最佳参数确定。输出分类识别结果和准确率。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 122鸡群优化算法蝙蝠优化算法 (xiaohongshu.com)

关于设计模式的一点总结

一、GoF 23种设计模式 1.分类 GoF 23种设计模式可分为几类&#xff1a;创建型、结构型和行为型。如下表 分类设计模式创建型单例模式、工厂方法模式、抽象工厂模式、原型模式、建造者模式结构型代理模式、适配器模式、装饰者模式、桥接模式、组合模式、门面模式、享元模式行…

使用Python做个可视化的“剪刀石头布”小游戏

目录 一、引言 二、环境准备与基础知识 三、游戏界面制作 四、游戏逻辑实现 五、代码示例 六、游戏测试与优化 七、扩展与改进 八、总结 一、引言 “剪刀石头布”是一种古老的手势游戏&#xff0c;它简单易懂&#xff0c;趣味性强&#xff0c;适合各个年龄段的人参与。…

勒索检测能力升级,亚信安全发布《勒索家族和勒索事件监控报告》

评论员简评 近期(12.08-12.14)共发生勒索事件119起&#xff0c;相较之前呈现持平趋势。 与上周相比&#xff0c;近期仍然流行的勒索家族为lockbit3和8base。在涉及的勒索家族中&#xff0c;活跃程度Top5的勒索家族分别是&#xff1a;lockbit3、siegedsec、dragonforce、8base和…

vue3中pdf打印问题处理

1 get请求参数问题 之前的请求是post得不到参数&#xff0c;今天发现的问题很奇怪&#xff0c;从前端进入网关&#xff0c;网关居然得不到参数。 前端代码 const print () > {let linkUrlStr proxy.$tool.getUrlStr(proxy.$api.invOrder.psiInvOrder.printSalOutstock,{a…

error:0308010C:digital envelope routines::unsupported 前端项目错误

直接启动命令中增加&#xff1a; SET NODE_OPTIONS--openssl-legacy-provider && vue-cli-service serve