模板初阶学习

✨前言✨

📘 博客主页:to Keep博客主页
🙆欢迎关注,👍点赞,📝留言评论
⏳首发时间:2023年11月21日
📨 博主码云地址:博主码云地址
📕参考书籍:《C++ Primer》《C++编程规范》
📢编程练习:牛客网+力扣网
由于博主目前也是处于一个学习的状态,如有讲的不对的地方,请一定联系我予以改正!!!

文章目录

  • 1 初识泛型编程
  • 2 函数模板
    • 2.1 概念
    • 2.2 原理
    • 2.3 函数模板的实例化
    • 2.4 模板参数的匹配原则
  • 3 类模板

1 初识泛型编程

我们之前学过一个交换的Swap函数,可以交换两个变量之间的值!但是我们后续在使用过程中就会发现,如果交换的两个变量的类型改变了,我们就必须要在写过一份!这样代码的复用率就太低了!那么我们在C++中为了解决这种代码复用率较低的问题。引用泛型编程这一概念!

泛型编程:编写一个与类型无关的通用代码!让编译器自己进行识别!这种是代码复用常见的手段!模板就是泛型编程的基础!

模板就可以简单理解为是通用的代码!以Swap函数为例:就是可以根据你传入的数据类型,编译器会生成对应类型的交换函数!模板可以分为:函数模板和类模板

2 函数模板

2.1 概念

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

template<typename T,typename X……>
返回值类型 函数名(参数列表){}

template表示这是一个模板,typename关键字是用来定义模板参数的关键字!也可以使用class关键字。但是不能用struct来代替class关键字!则我们可以写出Swap函数的模板:

template<typename T>

void Swap(T& x,T& y)
{
	T tmp = x;
	x = y;
	y = tmp;
}

int main()
{
	int a = 10;
	int b = 20;
	Swap(a,b);
	char x = '0';
	char y = '9';
	Swap(x, y);
	return 0;
}

2.2 原理

看起来我们使用的是同一份代码,但实际上我们用的不是同一份代码!在编译器编译阶段,编译器会根据传入的实参类型来推演生成我们所需要类型的Swap函数,比如说我们传入的实参是int类型那么此时编译器就会将模板参数换成int,从而调用!

2.3 函数模板的实例化

函数模板的实例化分为隐式实例化和显式实例化

上面我们所写的关于Swap函数,自己传入实参,由编译器自己进行识别推演的,我们称为隐式实例化!下面我们来介绍一下什么是显式实例化:

在函数名后的<>中指定模板参数类型

我们先来看这样一段代码:

template <typename P>
int ADD(P x,P y)
{
	return x + y;
}
int main()
{
	int a = 10;
	double b = 20.0;
	int ret = ADD(a, b);
	return 0;
}

在编译的时候就会出现报错,发现如下问题:
在这里插入图片描述这是因为在调用ADD函数时,编译器不知道是应该把int转换成double,还是把double转换成int!此时我们可以利用模板的显式实例化!

int ret = ADD<int>(a, b);

指明要将double转换成int类型!

2.4 模板参数的匹配原则

1️⃣一个非模板函数可以与一个同名的函数模板可以一起存在,并且该函数模板还是可以实例化生成同名非模板函数

int ADD(int a, int b)
{
	return a + b;
}
template <typename P>
int ADD(P x,P y)
{
	return x + y;
}
int main()
{
	int a = 10;
	int b = 20;
	ADD(a, b);//调用同名的非模板函数
	ADD<int>(10, 20);//编译器会调用特化的模板函数
	return 0;
}

2️⃣如果条件都相同,对于非模板函数与模板函数,会优先调用非模板函数,而不会从模板函数中在生成一个实例出来!如果模板函数能够产生一个更好匹配的函数,那么就会优先调用模板!

int ADD(int a, int b)
{
	return a + b;
}
template <typename P1,typename P2>
int ADD(P1 x, P2 y)
{
	return x + y;
}

int main()
{
	int a = 10;
	int b = 20;
	double c = 20.0;
	ADD(a, b);//优先调用非模板函数
	ADD(a, c);//优先调用模板函数

	return 0;
}

3️⃣模板函数不支持自动类型转换(隐式的类型转换,比如把double转换成int),普通函数支持自动类型转换!

3 类模板

格式类型:
template<class T1, class T2, …, class Tn>
class 类模板名
{
// 类内成员定义
};

之前我们在C语言中学过typedef关键字,我们只需要改变typedef后的数据类型,就可以更改类中所要存储的数据类型,代码如下:

typedef int Date;

class Stack {
private:
	Date* _a;
	int _capacity;
	int _top;
public:
	Stack(int capacity = 10){
		_a = new Date[capacity];
		_capacity = capacity;
		_top = 0;
	}
};

但是,这也是有局限性的,因为如果需要多个栈并且多个栈中的存储的数据类型不一样,我们也要多写几分类似的代码!类模板就可以很好的解决这个问题!

template <class T>
class Stack
{
private:
	T* _a;
	int _capacity;
	int _top;

public:
	Stack(int capacity = 4)
	{
		_a = new T[capacity];
		_top = 0;
		_capacity = capacity;
	}
};

类模板的实现原理和函数模板的原理是一样的,但是类模板是通过显示实例化,而不是让编译器自己进行推演!

int main()
{
	Stack<int> st1;//放int的栈
	Stack<double> st2;//放double的栈
	Stack<char> st3;//放char类型的栈

	return 0;
}

注意:通过类模板实例化的类不是和普通类一样,普通类的类名就是类型,实例化的类就是类名<数据类型>才是类型!
类模板中函数的声明与定义写法如下所示:

template <class T>
class Stack
{
private:
	T* _a;
	int _capacity;
	int _top;

public:
	Stack(int capacity = 4);
};

template <class T>
Stack<T>::Stack(int capacity = 4)//指定类型作用域
{
	_a = new T[capacity];
	_capacity = capacity;
	_top = 0;
}

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

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

相关文章

docker-compose安装harbor

docker-compose安装harbor 环境&#xff1a;centos7 1、安装docker 官方文档 https://docs.docker.com/engine/install/centos/ 1、卸载旧版本 $ sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate …

设计模式—结构型模式之享元模式

设计模式—结构型模式之享元模式 享元模式(Flyweight Pattern)&#xff0c;运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象&#xff0c;而这些对象都很相似&#xff0c;状态变化很小&#xff0c;可以实现对象的多次复用。对象结构型。 在享元模式中可以共…

linux制作 ext4镜像image 脚本demo

结构如下&#xff1a; build_linux_targetfs.sh #!/bin/bashCHECK_MARK"\033[0;32m\xE2\x9C\x94\033[0m" X_MARK"\033[0;1;31mX\033[0m"export TOP_DIR$PWD export TARGET_IMAGE_PATH$TOP_DIR/filesystem/targetfs-images export BSP_IMAGE_PATH${TOP_DI…

vue项目中element-ui对话框el-dialog嵌套显示时多了一个遮罩层解决办法

在对话框里又嵌套了一个对话框展示时&#xff0c;多了一个遮罩层&#xff0c;如下图所示&#xff1a; 解决办法如下&#xff1a; 给对话框添加append-to-body 属性&#xff0c;参考以下代码&#xff1a; <el-dialog :visible.sync"dialogVisible" append-to-body …

56、修改Integer缓存上限

第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a;修改Integer缓存上限 运行代码 Testpublic void integerTest() {int a 100;Integer b 100;System.out.println(a b);Integer a1 Integer.valueOf(127);Integer b1 127;System.out.println(a1 b1);Integer …

html滑动文章标题置顶

position: sticky; 基于用户的滚动位置来定位 首先封装一个组件 例如&#xff1a;AAA组件&#xff08;注意&#xff0c;只能有一层盒子&#xff0c;不能在外面继续包一层div&#xff09; <template><div class"box">{{title}}</div> </templa…

企业域名邮箱申请流程指南:轻松搭建高效的企业邮箱系统

对于企业和个人来说拥有自己的域名和邮箱是展示形象和开展业务的重要工具&#xff0c;很多初学者可能对企业域名邮箱申请流程感到迷惑。企业域名邮箱申请流程分两步申请域名和创建邮箱&#xff0c;本文将详细介绍这两个步骤&#xff0c;帮助大家更好地理解和操作。 一、申请域名…

【Linux】缓冲区+磁盘+动静态库

一、缓冲区 1、缓冲区的概念 缓冲区的本质就是一段用作缓存的内存。 2、缓冲区的意义 节省进程进行数据IO的时间。进程使用fwrite等函数把数据拷贝到缓冲区或者外设中。 3、缓冲区刷新策略 3.1、立即刷新&#xff08;无缓冲&#xff09;——ffush() 情况很少&#xff0c…

场景中的解剖学方向标记_vtkAnnotatedCubeActor

开发环境&#xff1a; Windows 11 家庭中文版Microsoft Visual Studio Community 2019VTK-9.3.0.rc0vtk-example参考代码 demo解决问题&#xff1a;显示标记当前视角、空间的方位&#xff0c;关键对象vtkAnnotatedCubeActor: vtkAnnotatedCubeActor 是一个混合3D 演员&#xf…

单体进化微服务:拆分、注册、调用、网关、过滤、治理、分布式事务

这里写目录标题 基本介绍生产-消费-网关父依赖生产者服务消费者服务网关服务common服务 感想 基本介绍 Spring Cloud 是一个用于构建分布式系统和微服务架构的开发工具包。它提供了一系列的功能和组件&#xff0c;用于解决微服务架构中的常见问题&#xff0c;如服务注册与发现…

《栈和队列》的模拟实现(顺序栈) (链队列)

目录 前言&#xff1a; 栈和队列&#xff1a; 栈&#xff1a; 队列&#xff1a; 模拟实现《栈》&#xff1a; 1.typedef数据类型 2.初始化栈 3.销毁栈 4.入栈 5.出栈 6.取栈顶元素 7.判断栈是否为空 8.栈的大小 9.打印栈 模拟实现《队列》 &#xff1a; 1.type…

vue3中使用全局自定义指令和组件自定义指令

这篇文章会教大家如何实现全局自定义指令和组件自定义指令 &#x1f4d3;全局自定义指令和组件自定义指令的区别&#xff0c;除了写法不同和作用不同&#xff0c;其他的包括生命周期的使用方法都是一致的&#xff0c;全局自定义指令在main.ts中注册后整个项目都可以使用&#x…

每日一题(LeetCode)----链表--两两交换链表中的节点

每日一题(LeetCode)----链表–两两交换链表中的节点 1.题目&#xff08;[24. 两两交换链表中的节点](https://leetcode.cn/problems/spiral-matrix/)&#xff09; 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内…

网站迁移到HTTPS,如何避免内容重复?

我们常说安装SSL证书不是件难事&#xff0c;但将网站迁移到HTTPS的过程却不那么容易。你不是真的在重新建立一个网站&#xff0c;但如果出了差错&#xff0c;百度会误认为这是个新网站&#xff0c;还可能判定你的网站内容重复。原因归结于你将使用不同的协议来呈现整个网站。HT…

python内容榜第三名

这是家常帖。 最近沉迷整理知识&#xff0c;和大家一起共同学习&#xff0c;共同进步。 越来越爱写博客被大家阅读认可的感觉了。我辛苦学习总结来的成果被大家喜爱。 今天荣登python领域内容榜 榜三&#xff0c;给了我很大的信心去坚持做这件事&#xff0c;知识传播&#xf…

CTF-栈溢出-基本ROP-【ret2syscall】

文章目录 ret2syscallBxMCTF 2023 Anti-Libcmainwrite_bufflush_obufreadintread_buf 思路exp ret2syscall 即控制程序执行系统调用&#xff0c;获取 shell。 BxMCTF 2023 Anti-Libc main write_buf 写入字符的&#xff0c;待会输出 flush_obuf 把字符输出到屏幕 read…

前景一片蓝海,Android音视频开发必备基础知识汇总

转瞬间&#xff0c;2023 已慢慢步入深冬&#xff0c;回首过去一年&#xff0c;音视频技术在经历一番风浪的侵袭过后&#xff0c;变得逐渐相对平静下来。 “内卷”之外&#xff0c;大家似乎更多了一份“理性”指导我们去做一些正确的事&#xff0c;追求技术在商业中的更高价值。…

华为ac+fit无线2层漫游配置案例

ap的管理dhcp在ac上&#xff0c;业务dhcp在汇聚交换机上、并且带2层漫游 R1: interface GigabitEthernet0/0/0 ip address 11.1.1.1 255.255.255.0 ip route-static 12.2.2.0 255.255.255.0 11.1.1.2 ip route-static 192.168.0.0 255.255.0.0 11.1.1.2 lsw1: vlan batch 100…

[AutoSar]在Davinci Configurator中导入Dbc Cdd 文件

目录 关键词平台说明一、实现步骤1.1 添加相关模块1.2 导入文件1.3 加载完成后点next而不是finish1.4 更新配置1.5 解决错误 关键词 嵌入式、C语言、autosar 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 一、实现…