C++_模板初阶

在面向对象中,我们可以使用重载来实现多态。

但是问题在于,重载的函数仅仅是类型不同,代码复用率比较低,只要有新的类型出现时,就要增加对应的函数;另一方面它的代码可维护性比较低,一个出错可能所有的重载均出错。

那么在C++中,我们可以使用模板来尽量避免这些问题。

一、函数模板

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

函数模板格式如下:

template<typename T1, typename T2,......,typename Tn>

返回值类型 函数名(参数列表){}

其中,typename是用来定义模板参数关键字,也可以使用class。

要注意模板和函数之间是不需要任何符号的,并且它们可以在同一行。

下面的代码就是使用函数模板的一个实例:

template <typename T>
void Swap(T& left,T& right)
{
	T temp = left;
	left = right;
	right = temp;
}

函数模板本身不是一个函数,而是“蓝图”,是编译器用使用方式产生特定具体类型函数的模具。

模板就是将本来应该我们做的重复的事情交给了编译器。

当使用了模板时,在编译器编译阶段,编译器需要根据传入的实参类型来推演生成对应的函数,然后供调用。

假如我们用double类型使用函数模板时,编译器通过对实参类型的推演,确定T为double,然后生成专门处理double类型参数的函数:

可以看到,类型仍然为double,变量的值也被成功交换。

实例化函数模板的方式有两种,一种是隐式实例化,另一种是显式实例化。

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

从监视1窗口可以看到,得到了正确的结果。

那么,根据刚才的Add函数模板及变量,能否这样隐式实例化呢?

Add(num0,num2);

根据编译器警告信息,可以明确是不可行的:

要处理这种状况,方法有两种,一种是用户自己强制类型转换:

Add((double)num0, num2);
Add(num0, (int)num2);

还有一种方法就是,显式实例化。

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

如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。

模板参数的匹配规则如下:

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

2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板;

3.模板函数不允许自动类型转换,但普通函数可以进行自动类型转换。

例如,func同时是函数,也是模板。现在在main函数中用不同的类型对其实例化,根据打印输出结果可知,当参数为int时,调用的是函数,当参数不为int时,调用的是根据模板生成的函数:

 二、类模板

类模板是编译器根据被实例化的类型生成具体类的模具。

在STL中,如vector,随处可见类模板的身影:

类模板的定义格式如下:

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

与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>
中即可。

类模板名字不是真正的类,实例化的结果才是真正的类。

一个类模板实例化的具体例子:

  

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android之消除APP图标的白色边框

有问题的效果&#xff1a; 解决方案&#xff1a; 第一步&#xff1a;app右键—>new—>Image Asset 第二步&#xff1a;上传Logo图标&#xff0c;选择每种分辨率&#xff0c;预览看效果&#xff0c;选择Resize&#xff0c;可以微调 第三步&#xff1a;点击 Next&#xff…

nbcio-boot升级到3.1后出现online表单新增报错

nbcio-boot升级springboot、mybatis-plus和JSQLParser后出现新增online表单的时候报错&#xff0c;如下&#xff1a; 2023-08-13 21:18:01.292 [http-nio-8080-exec-12] [1;31mERROR[0;39m [36mo.jeecg.common.exception.JeecgBootExceptionHandler:69[0;39m - Handler dispat…

【Bert101】最先进的 NLP 模型解释【01/4】

0 什么是伯特&#xff1f; BERT是来自【Bidirectional Encoder Representations from Transformers】变压器的双向编码器表示的缩写&#xff0c;是用于自然语言处理的机器学习&#xff08;ML&#xff09;模型。它由Google AI Language的研究人员于2018年开发&#xff0c;可作为…

免费实用的日记应用:Day One for Mac中文版

Day One for Mac是一款运行在Mac平台上的日记软件&#xff0c;你可以使用Day One for mac通过快速菜单栏条目、提醒系统和鼓舞人心的信息来编写更多内容&#xff0c;day one mac版还支持Dropbox同步功能&#xff0c;想要day one mac中文免费版的朋友赶紧来试试吧&#xff01; …

力扣刷题(C++)知识点

一&#xff0c;找到数组的中间位置 这个是错的&#xff0c;不能分开来 C vector<int>& nums 用法 创建一维数组vector&#xff1a; vector<int> nums; //不指定长度vector<int> nums(n); //指定长度为n c &#xff1c;numeric&#xff1e; accumul…

C语言——指针进阶

本章重点 字符指针数组指针指针数组数组传参和指针传参函数指针函数指针数组指向函数指针数组的指针回调函数指针和数组面试题的解析 1. 字符指针 在指针的类型中我们知道有一种指针类型为字符指针 char* int main() { char ch w; char *pc &ch; *pc w; return 0; }…

Java+Excel+POI+testNG基于数据驱动做一个简单的接口测试【杭州多测师_王sir】

一、创建一个apicases.xlsx放入到eclipse的resource里面&#xff0c;然后refresh刷新一下 二、在pom.xml文件中加入poi和testng的mvn repository、然后在eclipse的对应目录下放入features和plugins&#xff0c;重启eclipse就可以看到testNG了 <!--poi excel解析 --><d…

IDEA项目实践——Spring当中的切面AOP

系列文章目录 IDEA创建项目的操作步骤以及在虚拟机里面创建Scala的项目简单介绍 IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介 IDEWA项目实践——mybatis的一些基本原理以及案例 IDEA项目实践——动态SQL、关系映射、注解开发 IDEA项…

Django实现音乐网站 ⑽

使用Python Django框架制作一个音乐网站&#xff0c; 本篇主要是后台对歌曲类型、歌单功能原有功能进行部分功能实现和显示优化。 目录 歌曲类型功能优化 新增编辑 优化输入项标题显示 父类型显示改为下拉菜单 列表显示 父类型显示名称 过滤器增加父类型 歌单表功能优化…

从一到无穷大 #10 讨论 Apache IoTDB 大综述中看到的优劣势

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言问题定义新技术数据模型schemalessTsfile设计双MemTable高级可扩展查询其他 IotD…

【VSCode】报错:出现段错误解决办法 (Segmentation fault)

VScode报错&#xff1a;Segmentation fault (core dumped)的解决办法 解决Program received signal SIGSEGV, Segmentation fault.的辛酸 Linux环境下段错误的产生原因及调试方法小结 Linux下的段错误Segmentationfault产生的原因及调试方法经典.pdf 在程序中&#xff0c;TF…

Python-OpenCV中的图像处理-傅里叶变换

Python-OpenCV中的图像处理-傅里叶变换 傅里叶变换Numpy中的傅里叶变换Numpy中的傅里叶逆变换OpenCV中的傅里叶变换OpenCV中的傅里叶逆变换 DFT的性能优化不同滤波算子傅里叶变换对比 傅里叶变换 傅里叶变换经常被用来分析不同滤波器的频率特性。我们可以使用 2D 离散傅里叶变…

面试总结-webpack/git

说说你对webpack的理解 webpack 是一个静态模块打包器&#xff0c;整个打包过程就像是一条生产线&#xff0c;把资源从入口放进去&#xff0c;经过一系列的加工&#xff08;loader&#xff09;&#xff0c;最终转换成我们想要的结果&#xff0c;整个加工过程还会有监控&#x…

pytest 用例运行方式

一、命令行方式运行 执行某个目录下所有的用例&#xff0c;符合规范的所有用例 进入到对应的目录,直接执行pytest; 例如需要执行testcases 下的所有用例; 可以进入testcases 目录; 然后执行pytest 进入对应目录的上级目录,执行pytest 目录名称/ ; ; 例如需要执行testcases 下…

【rust/egui】(二)看看template的main函数:日志输出以及eframe run_native

说在前面 rust新手&#xff0c;egui没啥找到啥教程&#xff0c;这里自己记录下学习过程环境&#xff1a;windows11 22H2rust版本&#xff1a;rustc 1.71.1egui版本&#xff1a;0.22.0eframe版本&#xff1a;0.22.0上一篇&#xff1a;这里 开始 首先让我们看看main.rs中有些什么…

ROS2 学习(一)介绍,环境搭建,以及个人安装的一些建议

ROS2 学习 学习自b站课程&#xff1a;https://www.bilibili.com/video/BV16B4y1Q7jQ?p1 &#xff08;up主&#xff1a;古月居GYH&#xff09; ROS 介绍 Robot OS&#xff0c;为机器人开发提供了相对完善的 middleware&#xff0c;工具&#xff0c;软件等。 ROS1 对嵌入式设…

Qt6之QListWidget——Qt仿ToDesk侧边栏(1)

一、 QLitWidget概述 注意&#xff1a;本文不是简单翻译Qt文档或者接口函数&#xff0c;而侧重于无代码Qt设计器下演示使用。 QListWidget也称列表框类&#xff0c;它提供了一个类似于QListView提供的列表视图&#xff0c;但是它具有一个用于添加和删除项的经典的基于项的接口…

jupyter切换conda虚拟环境

环境安装 conda install nb_conda 进入你想使用的虚拟环境&#xff1a; conda activate your_env_name 在你想使用的conda虚拟环境中&#xff1a; conda install -y jupyter 在虚拟环境中安装jupyter&#xff1a; conda install -y jupyter 重启jupyter 此时我们已经把该安装…

yolov5部署 单线程与多线程对比

单线程 部署代码可参考&#xff1a; Yolov5 ONNX Runtime 的 C部署_爱钓鱼的歪猴的博客-CSDN博客 main.cpp #include "detector.h" #include <chrono> using namespace std;// 识别线程 void *detect_thread_entry(void *para){}int main(int argc, char *ar…

【正版系统】2023热门短剧SAAS版开源 | 小程序+APP+公众号H5

当我们在刷百度、D音、K手等各种新闻或短视频时经常会刷到剧情很有吸引力的短剧广告&#xff0c;我们点击广告链接即可进入短剧小程序&#xff0c;小程序运营者通过先免费看几集为诱耳然后在情节高潮时弹出充值或开VIP会员才能继续看的模式来赚钱&#xff0c;以超级赘婿、乡村小…