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返回类型的Add

	Add<int>(a, b);//若用显示调用则强制调用函数模板Add

	double a1 = 2.2, b1 = 3.3;
	Add(a1,b1);//只能通过调用模板函数Add来实现double类型的和

	Add(2, 2.2);//一个int类型,一个double类型,显然一个模板参数不够,因此会调用int类型Add
	return 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>才是一个类型

    //可以同时实现两个数据类型的Stack
	sti.push(6);
	std.push(6.6);
	cout << sti[0] << endl;
	cout << std[0] << endl;
	return 0;
}

        运行结果:

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

结语:

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

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

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

相关文章

内网DNS隐蔽隧道搭建之iodine工具

iodine iodine是基于C语言开发的&#xff0c;分为服务端和客户端。iodine支持转发模式和中继模式。其原理是&#xff1a;通过TAP虚拟网卡&#xff0c;在服务端建立一个局域网&#xff1b;在客户端&#xff0c;通过TAP建立一个虚拟网卡&#xff1b;两者通过DNS隧道连接&#xf…

YACS(上海计算机学会竞赛平台)2023年12月月赛——移动复位

移动复位 内存限制: 256 Mb时间限制: 1000 ms 题目描述 二维平面上有一个点。该点最初所在的位置称之为起点。接下来&#xff0c;该点接受了一串命令&#xff0c;每个命令可以用一个大写字母表示&#xff1a; R 表示该点沿 X 轴坐标正方向移动了一个单位&#xff1b;L 表示…

AI实景无人直播创业项目:开启自动直播新时代,一部手机即可实现增长

在当今社会&#xff0c;直播已经成为了人们日常生活中不可或缺的一部分。无论是商家推广产品、明星互动粉丝还是普通人分享生活&#xff0c;直播已经渗透到了各行各业。然而&#xff0c;传统直播方式存在着一些不足之处&#xff0c;如需现场主持人操作、高昂的费用等。近年来&a…

CentOs 环境下使用 Docker 部署 Ruoyi-Vue

CentOs 环境下使用 Docker 部署 Ruoyi-Vue RuoYi-Vue 项目下载地址 RuoYi-Vue: &#x1f389; 基于SpringBoot&#xff0c;Spring Security&#xff0c;JWT&#xff0c;Vue & Element 的前后端分离权限管理系统&#xff0c;同时提供了 Vue3 的版本 (gitee.com) Docker 部…

x-cmd pkg | tig - git 文本模式界面

目录 简介首次用户功能特点类似工具与竞品进一步探索 简介 tig 由 Jonas Fonseca 于 2006 年使用 C 语言创建的 git 交互式文本命令行工具。旨在开启交互模式快速浏览 git 存储库的信息以及 git 命令的运行。 首次用户 使用 x tig 即可自动下载并使用 在终端运行 eval "…

NeurIPS上新 | 从扩散模型、脑电表征,到AI for Science,微软亚洲研究院精选论文

编者按&#xff1a;欢迎阅读“科研上新”栏目&#xff01;“科研上新”汇聚了微软亚洲研究院最新的创新成果与科研动态。在这里&#xff0c;你可以快速浏览研究院的亮点资讯&#xff0c;保持对前沿领域的敏锐嗅觉&#xff0c;同时也能找到先进实用的开源工具。 本期“科研上新…

项目框架构建之6:编写通用主机基础类

本文是“项目框架构建”系列之6&#xff0c;本文介绍如何编写通用主机基础类。 1.为了构建通用主机&#xff0c;我们先创建主机接口IAppHost接口 接口需要有配置项&#xff0c;我们定义为HostConfiguration&#xff0c;比如我们希望用户可以设定他的工作目录&#xff0c;就可…

GLEE:一个模型搞定目标检测/实例分割/定位/跟踪/交互式分割等任务!性能SOTA!

GLEE&#xff0c;这是一个面向目标级别的基础模型&#xff0c;用于定位和识别图像和视频中的目标。通过一个统一的框架&#xff0c;GLEE实现了对开放世界场景中任意目标的检测、分割、跟踪、定位和识别&#xff0c;适用于各种目标感知任务。采用了一种协同学习策略&#xff0c;…

C之BS开发

一、 BS 概述与 boa 搭建 1.1 BS 模式开发概述 BS 模式&#xff1a; 浏览器与服务器模式&#xff0c; 即通过浏览器访问服务器的 Web 资源。 1.1.1 web 前端开发技术 主要包含&#xff1a; HTML 、 CSS 、 XML/JSON 、 Javascript 、 AJAX HTML 超文本标记语言 ( 英文全称…

华为欧拉安装部署:Oracle11g

一、环境准备 1、下载安装低版本的libaio包&#xff1b;libaio版本太高&#xff0c;会造成编译错误 查看libaio1库版本不能大于0.3.109 [oracles3 install]$ rpm -qa libaio libaio-0.3.110-12.el8.x86_64# 查看欧拉操作系统版本 [oraclelocalhost bin]$ cat /etc/os-release…

stable diffusion 基础教程-提示词之艺术风格用法

展现夕阳 golden hour, (rim lighting):1.2, warm tones, sun flare, soft shadows, vibrant colors, hazy glow, painterly effect, dreamy atmosphere阴影 chiaroscuro, (high contrast):1.2, dramatic shadows, bold highlights, moody atmosphere, captivating inte…

5-sql注入之文件读写

文章目录 SQL注入之文件读写1、文件读写注入的原理2、文件读写注入的条件读取文件写入文件 SQL注入之文件读写 1、文件读写注入的原理 就是利用文件的读写权限进行注入&#xff0c;它可以写入一句话木马&#xff0c;也可以读取系统文件的敏感信息。 2、文件读写注入的条件 …

02 Deep learning algorithm

Neural Networks target&#xff1a; inference&#xff08;prediction&#xff09;training my own modelpractical advice for building machine learning systemdecision Tress application: speech&#xff08;语音识别&#xff09; ----> images(计算机视觉)—> t…

MS713/MS713T:CMOS 低压、4Ω四路单刀单掷开关,替代ADG713

产品简述 MS713/MS713T 是一款单芯片 CMOS 4 路可选择开关&#xff0c;具有低 功耗、高开关速度、低导通阻抗、低漏电和高带宽特性。其工作 电压范围是 1.8V 到 5.5V &#xff0c;可以广泛应用在电池供电仪器仪表、新 一代的模数转换和数模转换系统中。其高带宽特性可用在 …

代码+视频,手把手教你R语言使用forestploter包绘制单组及双组森林图

森林图在论文中很常见&#xff0c;多用于表示多因素分析中的变量与结果变量的比值效应&#xff0c;可以用图示的方法比较直观的绘制出来。既往我们在文章《R语言快速绘制多因素回归分析森林图&#xff08;1&#xff09;》已经介绍了怎么绘制森林图&#xff0c;但是绘图比较简单…

SecOC中新鲜度值和MAC都按照完整的值来生成,但是在发送和认证的时候只会截取一部分。这边截取的部分一般取多长?由什么参数设定?

新鲜度值(Freshness Value, FV)和消息验证码(Message Authentication Code, MAC)是SecOC协议中用于保证数据的真实性和新鲜度的重要信息。它们的长度取决于不同的因素,如加密算法、安全级别、通信带宽等。 一般来说,FV和MAC的长度越长,安全性越高,但也会占用更多的通信…

Docker随笔

OverView 为什么需要Docker 如果我需要部署一个服务&#xff0c;那么我需要提前部署其他应用栈&#xff0c;不同的应用栈会依赖于不用的操作系统和环境。这样做会产生一些负面影响&#xff1a; 不同版本依赖较长的部署时间不同的Dev/Test/Prod环境 这时我们需要一个工具去解…

JumpServer3.0版本-资产管理

资产列表 资产列表可展示资产树和类型树,可以查看添加的所有资产 新增资产也是在此页面 在资产树上面右键可以创建新的子节点 比如这里我新建了个“腾讯云”节点 选中腾讯云节点,点击中间的“创建”按钮,新增资产 选择你的主机类型,我这是Linux 填写你资产的名称、IP必…

Java Arrays.copyOfRange的用法

Arrays.copyOfRange的使用方法&#xff1a; 将一个数组拷贝至另一个数组中 参数&#xff1a; original&#xff1a;第一个参数为要拷贝的数组对象 from&#xff1a;第二个参数为拷贝的开始位置&#xff08;包含&#xff09; to&#xff1a;第三个参数为拷贝的结束位置&#x…

AIGC实战——自回归模型(Autoregressive Model)

AIGC实战——自回归模型 0. 前言1. 长短期记忆网络基本原理2. Recipes 数据集3. 处理文本数据3.1 文本与图像数据处理的差异3.2 文本数据处理步骤 4. 构建 LSTM 模型4.1 模型架构4.2 LSTM 计算流程4.3 训练 LSTM 5. LSTM 模型分析小结系列链接 0. 前言 自回归模型 (Autoregres…