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 类模板名
{
// 类内成员定义
};

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

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

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

  

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

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

相关文章

Windows - UWP - 网络不好的情况下安装(微软商店)MicrosoftStore的应用

Windows - UWP - 网络不好的情况下安装&#xff08;微软商店&#xff09;MicrosoftStore的应用 前言 UWP虽然几乎被微软抛弃了&#xff0c;但不得不否认UWP应用给用户带来的体验。沙箱的运行方式加上微软的审核&#xff0c;用户使用起来非常放心&#xff0c;并且完美契合Wind…

最具性价比视频解析卡:Atlas300V,性能和能效业界两倍

华为推出“昇腾伙伴网络”&#xff08;简称APN&#xff09;合作伙伴计划&#xff0c;思腾合力凭借多年在AI行业的积累和自身的实力成为首家签署APN合作协议的公司&#xff0c;共同打造基于昇腾的软硬件AI基础架构解决方案&#xff0c;推进人工智能国产算力的进步和发展。

分支语句与循环语句(2)

3.3 do...while()循环 3.3.1 do语句的语法&#xff1a; do 循环语句; while(表达式); 3.3.2执行流程图&#xff1a; 3.3.3 do语句的特点 循环至少执行一次&#xff0c;使用的场景有限&#xff0c;所以不是经常使用。 打印1-10的整数&#xff1a; #define _CRT_SECURE_NO_WA…

c++ qt(第一部分)

c qt&#xff08;第一部分&#xff09; 一.认识QT 1.什么是QT Qt&#xff08;官方发音 [kju:t]&#xff0c;音同 cute&#xff09;是一个跨平台的 C 开发库&#xff0c;主要用来开发图形用户界面&#xff08;Graphical User Interface&#xff0c;GUI&#xff09;程序&#…

Multi-object navigation in real environments using hybrid policies 论文阅读

论文信息 题目&#xff1a;Multi-object navigation in real environments using hybrid policies 作者&#xff1a;Assem Sadek, Guillaume Bono 来源&#xff1a;CVPR 时间&#xff1a;2023 Abstract 机器人技术中的导航问题通常是通过 SLAM 和规划的结合来解决的。 最近…

[FPGA IP系列] 2分钟了解FPGA中的BRAM

FPGA设计中&#xff0c;BRAM是一项非常关键的内置存储资源&#xff0c;FPGA开发需要熟练使用BRAM&#xff0c;今天再复习一下BRAM的知识&#xff0c;包括BRAM的定义、组成、应用等等。 一、BRAM介绍 1、BRAM的定义 RAM是Random Access Memory&#xff0c;也就是随机访问数据…

natapp内网穿透

下载 参考 https://natapp.cn/article/natapp_newbie 注册免费通道 启动 ./natapp -authtoken9ab6b9040a624f40

带扩散器的超快速控制网

一、说明 自从稳定扩散风靡全球以来&#xff0c;人们一直在寻找更好地控制生成过程结果的方法。ControlNet提供了一个最小的界面&#xff0c;允许用户在很大程度上自定义生成过程。使用 ControlNet&#xff0c;用户可以轻松地使用不同的空间上下文&#xff08;如深度图、分割图…

SD卡相关资料

STM32429I-EVAL1 正点原子 ALIENTEK探索者STM32F4、ALIENTEK战舰STM32F1 V3 野火 野火STM32F103-V2霸道 中科蓝汛 AB5322B QFN32内部软开关蓝牙音箱

OpenCV基本操作——图像的基础操作

目录 图像的IO操作读取图像显示图像保存图像 绘制几何图形绘制直线绘制圆形绘制矩形向图像中添加文字效果展示 获取并修改图像中的像素点获取图像的属性图像通道的拆分与合并色彩空间的改变 图像的IO操作 读取图像 cv2.imread()import numpy as np import cv2 imgcv2.imread(…

四、web应用程序技术——HTTP

文章目录 1 HTTP请求2 HTTP响应3 HTTP方法4 URL5 HTTP消息头5.1 常用消息头5.2 请求消息头5.3 响应消息头 6 cookie7 状态码8 HTTP代理9 HTTP身份验证 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是访问万维网使用的核心通信协议&…

微信小程序调用map数据 并在wxml中对数组进行截取的操作

wxs文件的位置如图 实现数组截取 只保留五张图片 <wxs module"filter" src"./slicefunc.wxs"></wxs> <view class"wrap"><view class"search-box" bindtap"toSearch"><view class"v1"…