初步认识C++模版

前言

在C语言中,我们知道函数的形参需要指定类型,但是在C++中,我们可以模版实现各种类型参数的通用函数。

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

但是这里有不好的地方:

1. 重载函数的代码复用率较低,当有新类型出现的时候,需要用户自己新增对应函数

2. 代码的可维护性较低,一个出错可能导致所有的重载进出错

因此,C++研究出了模版来实现函数的多类型形参使用。

2. 函数模版

2.1 什么是函数模版

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

2.2 函数模版格式

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

在交换函数中的使用:

template<typename T>
void swap(T& x,T& y)
{T temp = x;x = y;y = temp;
}

注意:typename可以用来定义模版参数关键字,也可以用class,但是不能用struct。

2.3 函数模版的原理

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

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

2.4 函数模版实例化

当不同类型的参数使用函数模版时,称为函数模版的实例化。

模版实例化分为:隐式实例化和显式实例化。

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

template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
int main()
{
int a1 = 10, a2 = 20;
double d1 = 10.0, d2 = 20.0;
Add(a1, a2);
Add(d1, d2);
Add(a1,d1);
return 0;
}

这段代码是不能通过编译的,因为在第一个ADD的时候,模版将T推演为int类型,而第二个add则将T推演为double类型,然而模版参数列表只有一个T,所以会报错。

这时就需要处理,有两种方法:

1. 用户自己强制转换

Add(a1,(int )d1);

2. 使用显式实例化:在函数名后的<>中指定模版参数的实际类型

int main(void)
{
int a = 10;
double b = 20.0;
// 显式实例化
Add<int>(a, b);
return 0;
}

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

2.5 模版参数的匹配原则

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

// 专门处理int的加法函数
int Add(int left, int right)
{
return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right)
{
return left + right;
}
void Test()
{
Add(1, 2); // 与非模板函数匹配,编译器不需要特化
Add<int>(1, 2); // 调用编译器特化的Add版本
}

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

// 专门处理int的加法函数
int Add(int left, int right)
{
return left + right;
比特就业课
3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
3. 类模板
3.1 类模板的定义格式
}
// 通用加法函数
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{
return left + right;
}
void Test()
{
Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化
Add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的
Add函数
}

3. 类模版

3.1 定义格式

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

#include<iostream>
using namespace std;
// 类模版
template<typename T>
class Stack
{
public:
Stack(size_t capacity = 4)
{
_array = new T[capacity];
_capacity = capacity;
_size = 0;
}
void Push(const T& data);
private:
T* _array;
size_t _capacity;
size_t _size;
};
// 模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误,具体原因后面会讲
template<class T>
void Stack<T>::Push(const T& data)
{
// 扩容
_array[_size] = data;
++_size;
}
int main()
{
Stack<int> st1; // int
Stack<double> st2; // double
return 0;
}

注意:每个函数模版定义后的作用域只在后面的一个短区域,因此需要定义多次函数模板。

3.2  类模版的实例化

类模版的实例化与函数模版不同,类模版的实例化需要在名字后面跟<>,将类型放在<>中间,类模板的名字不是真正的类,实例化的结果才是真正的类。

// Stack是类名,Stack<int>才是类型
Stack<int> st1; // int
Stack<double> st2; // double

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

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

相关文章

linux下将txt转成xlsx

在Linux环境下&#xff0c;可以使用Python的pandas库将TXT文件转换为Excel文件。以下是一个简单的示例代码&#xff1a; 首先&#xff0c;确保安装了pandas和openpyxl库&#xff1a; pip install pandas openpyxl 然后&#xff0c;使用以下Python脚本将TXT文件转换为Excel文件…

基于单片机汽车驾驶防瞌睡防疲劳报警器自动熄火设计

文章目录 前言资料获取设计介绍功能介绍设计程序具体实现截图设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对…

项目第四弹:交换机、队列、绑定信息管理模块分析与代码实现

项目第四弹&#xff1a;交换机、队列、绑定信息管理模块分析与代码实现 一、模块设计分析1.模块划分2.功能需求 二、交换机模块的实现1.交换机结构体的实现2.交换机持久化管理模块的实现3.交换机对外管理模块实现声明、删除交换机时的查找不能复用exists函数为何持久化管理模块…

查找算法 01分块查找

自己设计一个分块查找的例子&#xff0c;不少于15个数据元素&#xff0c;并建立分块查找的索引 基于上述例子&#xff0c;计算查找成功的ASL、查找失败的ASL 拓展&#xff1a; ‌‌分块查找的平均查找长度&#xff08;‌ASL&#xff09;的计算公式如下‌&#xff1a;‌ ‌顺序…

ESP32 JTAG 调试

前言 个人邮箱&#xff1a;zhangyixu02gmail.com本人使用的是 Ubuntu 环境&#xff0c;采用 GDB 方式进行调试。对于新手&#xff0c;我个人还是建议参考ESP32S3学习笔记&#xff08;0&#xff09;—— Vscode IDF环境搭建及OpenOCD调试介绍进行图形化的方式调试。如果是希望在…

占领矩阵-第15届蓝桥省赛Scratch中级组真题第5题

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第190讲。 如果想持续关注Scratch蓝桥真题解读&#xff0c;可以点击《Scratch蓝桥杯历年真题》并订阅合集&#xff0c;…

Python酷库之旅-第三方库Pandas(122)

目录 一、用法精讲 541、pandas.DataFrame.take方法 541-1、语法 541-2、参数 541-3、功能 541-4、返回值 541-5、说明 541-6、用法 541-6-1、数据准备 541-6-2、代码示例 541-6-3、结果输出 542、pandas.DataFrame.truncate方法 542-1、语法 542-2、参数 542-3…

植保无人机是朝阳产业还是夕阳产业?

植保无人机产业是朝阳产业还是夕阳产业&#xff0c;可以从多个维度进行分析&#xff1a; 一、市场需求与增长趋势 市场需求&#xff1a;随着农业现代化的推进和劳动力成本的上升&#xff0c;植保无人机因其高效、安全、节省农药等优势&#xff0c;在农业生产中的应用越来越广…

自闭症能上寄宿学校吗?了解解答与选择

在探讨自闭症儿童教育的话题时&#xff0c;寄宿学校作为一种特殊的教育模式&#xff0c;常常引发家长们的关注与讨论。对于自闭症儿童而言&#xff0c;寄宿学校既是一个充满挑战的新环境&#xff0c;也是一个能够促进他们独立成长与社交融合的重要平台。今天&#xff0c;我们将…

自制数据库空洞率清理工具-C版-03-EasyClean-V1.3(支持南大通用数据库Gbase8a)

目录 一、环境信息 二、简述 三、升级点 四、支持功能 五、空洞率 六、工具流程图 1、流程描述 2、注意点 &#xff08;1&#xff09;方法一 &#xff08;2&#xff09;方法二 七、清理空洞率流程图 八、安装包下载地址 九、参数介绍 1、命令模板 2、命令样例 3…

【C语言-数据结构】单链表的定义

单链表的定义&#xff08;实现&#xff09; 比较顺序表和单链表的物理存储结构就能够清楚地发现二者的区别 用代码定义一个单链表 typedef struct LNode{ElemType data; //每个结点存放一个数据元素struct LNode* next; //指针指向下一个结点 }LNode, *LinkList;//要表示一个…

[JavaEE] TCP协议

目录 一、TCP协议段格式 二、TCP确保传输可靠的机制 2.1 确认应答 2.2 超时重传 2.3 连接管理 2.3.1 三次握手 2.3.2 四次挥手 2.4 滑动窗口 2.4.1 基础知识 2.4.2 两种丢包情况 2.4.2.1 数据报已经抵达&#xff0c;ACK丢包 2.4.2.2 数据包丢包 2.5 流量控制…

【时时三省】(C语言基础)指针笔试题2

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 笔试题2 这里的0x1是16进制的1 跟十进制的1一样 这道题考察的是&#xff1a;指针类型决定了指针的运算 p是上面结构体的指针 它指向的大小结果是20个字节 指针…

项目第五弹:队列消息管理模块

项目第五弹&#xff1a;队列消息管理模块 一、消息如何组织并管理1.消息结构体2.消息持久化管理模块设计1.数据消息文件名2.临时消息文件名3.对外接口与包含成员 二、自定义应用层协议解决文件读写的粘包问题1.Length-Value协议 三、队列消息管理模块设计1.待确认消息哈希表2.待…

[数据结构]动态顺序表的实现与应用

文章目录 一、引言二、动态顺序表的基本概念三、动态顺序表的实现1、结构体定义2、初始化3、销毁4、扩容5、缩容5、打印6、增删查改 四、分析动态顺序表1、存储方式2、优点3、缺点 五、总结1、练习题2、源代码 一、引言 想象一下&#xff0c;你有一个箱子&#xff08;静态顺序…

【医学半监督】对比互补掩蔽的自监督预训练半监督心脏图像分割

SELF-SUPERVISED PRE-TRAINING BASED ON CONTRASTIVE COMPLEMENTARY MASKING FOR SEMI-SUPERVISED CARDIAC IMAGE SEGMENTATION 2024 IEEE International Symposium on Biomedical Imaging (ISBI) 摘要: 心脏结构分割对心脏病诊断非常重要,而使用大量注释的深度学习在这项任…

Buck变换器闭环控制,simulink仿真模型(适合初学者学习)

Buck变换器&#xff0c;又称为降压斩波器&#xff0c;是一种常见的DC-DC转换器&#xff0c;广泛应用于电源管理领域。它通过开关元件&#xff08;通常是MOSFET或BJT&#xff09;的导通与截止&#xff0c;改变输入电压到负载的平均电压&#xff0c;从而实现电压的降低。在实际应…

harbor私有镜像仓库,搭建及管理

私有镜像仓库 docker-distribution docker的镜像仓库&#xff0c;默认端口号5000 做个仓库&#xff0c;把镜像放里头&#xff0c;用什么服务&#xff0c;起什么容器 vmware公司在docker私有仓库的基础上做了一个web页面&#xff0c;是harbor docker可以把仓库的镜像下载到本地&…

tauri嵌入自定义目录/文件,并在代码中读取文件内容的操作流程

可以看官方文档&#xff1a;Embedding Additional Files | Tauri Apps 在绑定了文件之后&#xff0c;可以在js中访问嵌入的文件或者在rust中读取嵌入的文件内容&#xff0c;详细的配置操作如下。 在src-tauri中创建自定义文件夹或文件&#xff0c;并在在tauri.conf.json中配置…

Java多线程Thread及其原理深度解析

文章目录 1. 实现多线程的方式2. Thread 部分源码2.1. native 方法注册2.2. Thread 中的成员变量2.3. Thread 构造方法与初始化2.4. Thread 线程状态与操作系统状态2.4. start() 与 run() 方法2.5. sleep() 方法2.6. join() 方法2.7. interrupt() 方法 本文参考&#xff1a; 线…