C++(10)——模板

news2024/11/18 11:39:08

目录

    1.什么是泛式编程以及模板的引入:

2. 模板:

2.1 函数模板:

2.2 类模板:


    1.什么是泛式编程以及模板的引入:

      在之前排序的部分中,为了完成某个特定功能,经常会用到交换函数,即:Swap。在C语言中,针对不同类型的变量进行交换,都需要专门编写一个符合类型的交换函数,例如:

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

       这种方法太过复杂,并且,上面三个函数的结构基本一致,不一样的只有每个函数参数的类型。于是,在C++中,便引入了泛式编程,即:编写与类型无关的通用代码,是代码复用的一种手段。来解决上述问题。而对于本篇文章的主题模板,便是泛式编程的基础。

2. 模板:

模板可以分为两类,分别是函数模板和类模板,下面将分开对二者进行介绍:

2.1 函数模板:

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

      对于函数模板的使用,需要借助关键字template来实现,下面将针对于上面的交换函数Swap来介绍关键字的大致使用方法:

template<typename T>

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

       其中,typename是用来定义模板参数关键字,也可以使用class。在定义完模板关键字后,便可以用定义的模板关键字来代替函数中的类型。

      在使用时,直接向函数传递参数即可,例如对于下方的代码:

int main()
{
	int a = 1;
	int b = 2;
	Swap(a, b);
	cout << a << " " << b << endl;

	double i = 1.1;
	double n = 2.2;
	Swap(i, n);
	cout << i << " " << n << endl;
	return 0;
}

运行结果为:

       对于模板如何工作的原理,大致可以认为函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器
      在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。

     对于上述过程,把具体类型的参数传递给函数形参,推断出T的类型的过程称之为模板的推演,把推演后,编写函数的过程称之为模板实例化。

上述模板参数在定义时,只是针对单一类型。假如传递的参数有多个不同的类型,可以通过定义不同的模板参数来解决,例如:

template<typename X, typename Y>
void Cout( X& a, Y& b)
{
	cout << a << b << endl;

}

传递参数如下:

int main()
{
	int i = 1;
	double n = 1.1;

	Cout(i, n);
	Cout(n, i);
	return 0;
}

运行结果如下:

当模板参数的数量小于传递参数的类型时,例如:

template<typename A>
A Add(A x, A y)
{
	return x + y;
}

int main()
{
	int i = 1;
	double n = 1.1;

	Add(i, n);
	return 0;
}

 此时运行代码,编译器会报错。

上述函数模板参数实例化可以称之为隐式实例化,同时,也有显式实例化,方法如下:

template<typename A>
A Add(A x, A y)
{
	return x + y;
}

int main()
{
	int i = 1;
	double n = 1.1;

	cout << Add<int>(i, n) << endl;
	return 0;
}

此时,double类型的变量n会在使用时被转类型为int,运行上述代码,结果为:

2.2 类模板:

对于下面一个简单的栈:

class Stack
{
public:
	Stack(int capacity = 4)
	{
		cout << "Stack( int capacity = 4)" << endl;
		_a = new int[capacity];
		_capacity = capacity;
		_top = _capacity;
	}

	~Stack()
	{
		cout << "~Stack()" << endl;
		delete[]_a;
		_a = nullptr;
		_top = 0;
		_capacity = 0;
	}
private:
	int* _a;
	int _top;
	int _capacity;
};

在之前数据结构的相关文章中,假设需要栈存储不同类型的数据,通常都是利用typedef来完成,即:

typedef int STDataType;

class Stack
{
public:
	Stack(int capacity = 4)
	{
		cout << "Stack( int capacity = 4)" << endl;
		_a = new STDataType[capacity];
		_capacity = capacity;
		_top = _capacity;
	}

	~Stack()
	{
		cout << "~Stack()" << endl;
		delete[]_a;
		_a = nullptr;
		_top = 0;
		_capacity = 0;
	}
private:
	STDataType* _a;
	int _top;
	int _capacity;
};

但是这种做法同样存在缺点,即只能针对一种单一的类型,如果需要存储两种不同类型的数据,则需要将上述代码进行一次复制,再改写typedef等内容。这样的作法过于麻烦,并且重复性过高。而对于类模板,可以很好的解决问题,方法如下:

template<typename T>

class Stack
{
public:
	Stack(int capacity = 4)
	{
		cout << "Stack( int capacity = 4)" << endl;
		_a = new T[capacity];
		_capacity = capacity;
		_top = _capacity;
	}

	~Stack()
	{
		cout << "~Stack()" << endl;
		delete[]_a;
		_a = nullptr;
		_top = 0;
		_capacity = 0;
	}
private:
	T* _a;
	int _top;
	int _capacity;
};
int main()
{
	return 0;
}

在传参时,与函数可以隐式实例化和显式实例化不同,类模板只能显式实例化,例如需要存储int,double两个类型的变量,显式实例化为:

Stack<int> s1;
	Stack<double> s2;

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

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

相关文章

Tensorflow2.0笔记 - 修改形状和维度

本次笔记主要使用reshape&#xff0c;transpose&#xff0c;expand_dim&#xff0c;和squeeze对tensor的形状和维度进行操作。 import tensorflow as tf import numpy as nptf.__version__#tensor的shape和维数获取 #假设下面这个tensor表示4张28*28*3的图片 tensor tf.rando…

Android代码混淆

Android之代码混淆 代码混淆的作用设置混淆1. 在模块目录下的 build.gradle 文件中配置以下代码2. 在 proguard-rules.pro 文件中添加混淆规则 通用混淆规则常用匹配符常用命令注意事项如何查看是否已混淆 代码混淆的作用 1.令 APK 难以被逆向工程&#xff0c;即很大程度上增加…

JVM 内存布局

内存区域分布介绍&#xff1a; jvm内存布局是理解Java应用程序运行时内存管理的重要一部分。JVM内存分为几个区域&#xff0c;每个区域有不同的作用。以下是JVM内存布局详细说明&#xff1a; JVM内存分布图&#xff1a; JVM内存区域详细说明&#xff1a; 方法区&#xff08;M…

遥感影像-语义分割数据集:Landsat8云数据集详细介绍及训练样本处理流程

原始数据集详情 简介&#xff1a;该云数据集包括RGB三通道的高分辨率图像&#xff0c;在全球不同区域的分辨率15米。这些图像采集自Lansat8的五种主要土地覆盖类型&#xff0c;即水、植被、湿地、城市、冰雪和贫瘠土地。 KeyValue卫星类型landsat8覆盖区域未知场景水、植被、…

Docker之概述与安装

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《Docker之概述与安装》。&#x1f3af;&#x1f…

笔记系统的部署架构

前天给笔记系统打了0.0.3的tag&#xff0c;一个简单的全栈功能闭环基本完成。既然是开源&#xff0c;因此&#xff0c;这里有必要分享一下部署结构&#xff0c;希望能够获得小伙伴们的反馈。 目前整个系统采用docker容器来部署。应用介绍 auth_app: 登录/注册的前端应用 web_ap…

9个自媒体音频创作平台(附链接通道)

​划到最后“阅读原文” ——进入官网 Hi&#xff0c;我是胡猛夫&#xff0c;每天分享实用运营工具&#xff01; 更多资源&#xff0c;更多内容&#xff0c;欢迎交流&#xff01;公 号 | 微视角文化 》》精彩推荐 >>微视角文化知识库&#xff1a;移动的自媒体运营百科全…

【Python机器学习】深度学习——调参

先用MLPClassifier应用到two_moons数据集上&#xff1a; from sklearn.neural_network import MLPClassifier from sklearn.datasets import make_moons from sklearn.model_selection import train_test_split import mglearn import matplotlib.pyplot as pltplt.rcParams[f…

UOS Python+Qt5实现声卡回路测试

1.回路治具设计&#xff1a; 2.Ui界面&#xff1a; 3.源代码&#xff1a; # -*- coding: utf-8 -*-# Form implementation generated from reading ui file SoundTestWinFrm.ui # # Created by: PyQt5 UI code generator 5.15.2 # # WARNING: Any manual changes made to this…

【VRTK】【Unity】【游戏开发】更多技巧

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概述】 本篇将较为零散但常用的VRTK开发技巧集合在一起,主要内容: 创建物理手震动反馈高亮互动对象【创建物理手】 非物理手状态下,你的手会直接…

BikeDNA(四)初始化参考数据

BikeDNA&#xff08;四&#xff09;初始化参考数据 这本笔记本&#xff1a; 加载定义研究区域的多边形&#xff0c;然后为研究区域创建网格叠加。加载参考数据。处理参考数据以创建分析所需的网络结构和属性。 先决条件和条件 输入/输出 config.yml 必须提前设置。 此笔记本…

力扣|2023华为秋招冲刺

文章目录 第一关&#xff1a;2023 年 7 月面试题挑战第二关&#xff1a;2023 年 6 月面试题挑战第三关&#xff1a;2023 年 5 月面试题挑战 第一关&#xff1a;2023 年 7 月面试题挑战 class Solution { public:void reverseWord(vector<char>& s,int l,int r){for(i…

教程-右键用vscode(新窗口)打开文件或目录

通过本文可以提高效率&#xff0c;用起来更爽更高效。 本文实现了&#xff08;windows系统&#xff09;&#xff1a; 右键-用vscode(当前窗口)打开文件或目录右键-用vscode-新窗口打开文件或目录 注意&#xff1a; 下面的安装路径要更改为您实际的路径 具体配置步骤&#x…

066:vue中实现二维数组的全选、全不选、反选、部分全选功能(图文示例)

第061个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下,本专栏提供行之有效的源代码示例和信息点介绍,做到灵活运用。 (1)提供vue2的一些基本操作:安装、引用,模板使用,computed,watch,生命周期(beforeCreate,created,beforeM…

面向零信任架构的访问安全态势评估

伴随着“云大物移”等新兴 IT 技术的快速发展&#xff0c;企业数字化转型使得 IT 业务的网络环境更加复杂多样&#xff0c;企业数字资源的安全防护正面临着前所未有的压力与威胁。零信任安全架构放弃了传统基于“边界”的安全模型&#xff0c;以访问上下文的安全态势感知为基础…

如何优雅的只在当前页面中覆盖ui库中组件的样式(vue的问题)

首先我们vue文件的样式都是写在<style lang"less" scoped></style>标签中的&#xff0c;加scoped是为了使得样式只在当前页面有效。那么问题来了&#xff0c;看图&#xff1a; 我们正常写的所有样式&#xff0c;都会被加上[data-v-23d425f8]这个属性&…

C#进阶-IIS服务器发布ASP.NET项目

对于云服务器&#xff0c;程序员一般不会陌生&#xff0c;如果项目需要发布到现网&#xff0c;那么服务器是必不可缺的一项硬性条件&#xff0c;那么如何在云服务器上部署一个项目&#xff0c;需要做哪些配置准备&#xff0c;下面就由本文档为大家讲解&#xff0c;本篇以 IIS服…

小学生练字神器,在线字帖生成器网站源码

源码介绍 帮助小学生规范汉字书写&#xff0c;提高汉字书写水平&#xff0c;在线小学生练字神器&#xff01;它不仅功能强大&#xff0c;而且完全免费&#xff0c;是每个小学生必备的练字工具。 海量字库&#xff1a;收录9574个常用汉字&#xff0c;满足小学生的学习需求。多…

R语言【paleobioDB】——pbdb_intervals():通过参数选择,返回多个地层年代段的基本信息

Package paleobioDB version 0.7.0 paleobioDB 包在2020年已经停止更新&#xff0c;该包依赖PBDB v1 API。 可以选择在Index of /src/contrib/Archive/paleobioDB (r-project.org)下载安装包后&#xff0c;执行本地安装。 Usage pbdb_interval (id, ...) Arguments 参数【..…

【Emgu.CV教程】5.1、几何变换之平移

图像的几何变换对于图像处理来说&#xff0c;也是最基础的那一档次&#xff0c;包括平移、旋转、缩放、透视变换等等&#xff0c;也就是对图像整理形状的改变&#xff0c;用到的函数都比较简单&#xff0c;理解起来也很容易。但是为了凑字数&#xff0c;还是一个函数一个函数的…