C++:模板的相关内容

news2024/11/19 20:33:23

文章目录

  • 泛型编程
  • 函数模板
  • 类模板
  • 非类型模板参数
  • 模板的特化

本篇介绍一部分关于C++中模板使用的问题,模板是C++的一大特色,需要在实际运用中体会它的妙处

泛型编程

为了知道什么是泛型编程,先来看,如何实现对于所有类型都使用的交换函数?

在C语言中这个实现是不可以的,因为没有函数重载,在C++中引入了函数重载的概念,根据函数参数的类型不同在寻找符号表的时候函数名不同,因此构成了函数重载,即使使用函数重载可以解决这个问题,函数重载依旧有很多弊端,比如同样的代码语句逻辑一摸一样,只有最后的函数参数的类型和函数体中的类型不一样,因此这里引入了模板的概念:

那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码

因此就有了函数模板的概念

函数模板

格式:

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

因此swap函数就可以写成

template<typename T>
void Swap( T& left, T& right)
{
T temp = left;
left = right;
right = temp;
}

这里需要注意的是,typename是用来定义模板参数关键字,也可以使用class

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

那实际函数调用的时候,编译器调用的是同一个函数吗,其实并不是这样

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

类模板

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

非类型模板参数

模板参数主要有两种,一种是类型形参,另外一种是非类型形参

  • 类型形参:出现在模板参数列表中,也就是在class或者typename后面的参数类型名称就是类型形参
  • 非类型形参:用一个常量作为类模板的一个参数,在类模板中可以将该参数作为常量来使用
namespace static_array
{
	// 定义一个模板类型的静态数组
	template<class T, size_t N = 10>
	class array
	{
	public:
		T& operator[](size_t index) 
		{ 
			return _array[index]; 
		}
		const T& operator[](size_t index) const 
		{ 
			return _array[index]; 
		}
		size_t size() const 
		{ 
			return _size; 
		}
		bool empty() const 
		{ 
			return 0 == _size; 
		}
	private:
		T _array[N];
		size_t _size;
	};
}

以上面的为例,通过这样的非类型模板参数可以实现定义一个常量的功能

值得注意的有下面两点:

  1. 浮点数,类对象和字符串不能作为非类型模板参数
  2. 非类型模板参数必须在编译前就确定,因为编译器要根据这个值开辟空间等操作

模板的特化

什么是模板的特化?

模板可以缩减代码的重复性,也就是可以实现一些和类型不相关的代码,但是也会有特殊的情况,比如说对于一些特殊的类型就会得到一些错误的结果,如果遇到这种情况该如何处理呢?

C++就引入了特化的概念,对于特殊的情况可以采用特殊的结果进行处理,那么有什么场景可以对这些进行使用?

以下面的例子为例:

#include <bits/stdc++.h>
using namespace std;

template <class T>
bool Less(T a, T b)
{
	return a < b;
}

int main()
{
	int p = 2;
	int q = 1;
	cout << Less(1, 2) << endl;
	cout << Less(1.1, 2.2) << endl;
	cout << Less(&p, &q) << endl;
	return 0;
}

运行结果如下

在这里插入图片描述

问题此时就出现了,对于模板来说,它可以比较各种类型的值,但是对于指针类型来说,它只能把指针的地址当成一个值来进行比较,因此是无法得到正确的结果的,此时可以用特化的原理来解决问题:

#include <bits/stdc++.h>
using namespace std;

template <class T>
bool Less(T a, T b)
{
	return a < b;
}

template <>
bool Less<int*>(int* a, int* b)
{
	return (*a) < (*b);
}

int main()
{
	int p = 2;
	int q = 1;
	cout << Less(1, 2) << endl;
	cout << Less(1.1, 2.2) << endl;
	cout << Less(&p, &q) << endl;
	return 0;
}

运行结果如下

在这里插入图片描述
上面的写法就是函数模板的特化,有下面一些需要注意的步骤

  • 必须有一个基础的函数模板
  • 关键字template后要带一个尖括号
  • 函数名后要带尖括号,内容是要被特化的类型
  • 函数的参数表要和模板函数的基础参数类型完全相同,才能实现函数模板的特化

注意,一般不使用函数特化,为了实现简单都是直接将函数给出,这样更加便携

#include <bits/stdc++.h>
using namespace std;

template <class T>
bool Less(T a, T b)
{
	return a < b;
}

// 直接给出函数,这样阅读起来更加便捷,可读性更高
bool Less(int* a, int* b)
{
	return (*a) < (*b);
}

int main()
{
	int p = 2;
	int q = 1;
	cout << Less(1, 2) << endl;
	cout << Less(1.1, 2.2) << endl;
	cout << Less(&p, &q) << endl;
	return 0;
}

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

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

相关文章

基于统计学库statsmodel实现时间序列预测

文章目录 1.数据探索与清洗2.假设检验&#xff1a;平稳性检验3.差分处理4.绘制ACF与PACF图像&#xff0c;完成模型选择4.建立ARIMA和SARIMA模型5.解读summary6.确定最终的模型 ARIMA模型在统计学上的三大基本假设&#xff1a; 时间序列具有平稳性&#xff08;stationary&#x…

【Bug处理】E0265 函数 “SizeClass::RoundUp“ (已声明 所在行数:62)不可访问

错误描述&#xff1a; 严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E0265 函数 “SizeClass::RoundUp” (已声明 所在行数:62&#xff0c;所属文件:“D:\CSTUDY\项目\高并发内存池\CONCURRENT_MEMORY_POOL\Common.h”) 不可访问 Concurrent_Memory_Pool D:\CStudy\…

10分钟搞懂,Python接口自动化测试-接口依赖-实战教程

一、场景说明 在面试接口自动化时&#xff0c;经常会问&#xff0c;其他接口调用的前提条件是当前用户必须是登录状态&#xff0c;如何处理接口依赖&#xff1f; 在此之前我们介绍过session管理器保存会话状态。如果接口请求需要携带token&#xff0c;那么又如果处理呢&#…

线性回归模型进行特征重要性分析

目的 线性回归是很常用的模型&#xff1b;在局部可解释性上也经常用到。 数据归一化 归一化通常是为了确保不同特征之间的数值范围差异不会对线性模型的训练产生过大的影响。在某些情况下&#xff0c;特征归一化可以提高模型的性能&#xff0c;但并不是所有情况下都需要进行归一…

点燃市场热情,让产品风靡全球——实用推广策略大揭秘!

文章目录 一、实用推广策略的重要性1. 提高产品知名度和认可度2. 拓展产品市场和用户群体3. 增强企业品牌形象和市场竞争力 二、实用推广策略的种类1. 社交媒体推广2. 定向推广3. 口碑营销4. 内容推广 三、实用推广策略的实施步骤1. 研究目标用户和市场需求&#xff0c;明确产品…

从开发到测试再到发布,全方位解析项目上线的完美路程!

文章目录 开发技术经理工作经验产品需求讨论项目开发计划制定控制项目风险技术小组日常管理工作进度检验与管理任务分配Code审查指导、培训普通开发工程师审核开发工程师的设计与研发质量 分布式项目架构经验1.技术架构2.网络架构3.数据库设计4.自动化部署5.监控和日志6.性能评…

【动态规划】123. 买卖股票的最佳时机 III、188. 买卖股票的最佳时机 IV

提示&#xff1a;努力生活&#xff0c;开心、快乐的一天 文章目录 123. 买卖股票的最佳时机 III&#x1f4a1;解题思路&#x1f914;遇到的问题&#x1f4bb;代码实现&#x1f3af;题目总结 188. 买卖股票的最佳时机 IV&#x1f4a1;解题思路&#x1f914;遇到的问题&#x1f4…

智能优化算法——混合领导优化算法(MatlabMatlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

LabVIEW为什么不能在RT机箱内看到NI-IMAQ设备

LabVIEW为什么不能在RT机箱内看到NI-IMAQ设备 最近把NI-IMAQ更新到最新的1394版本。这个新驱动工作良好。但是&#xff0c;当打开MAX&#xff0c;NII MAQ设备却在RT PXI机箱里找不到。 问题最有可能是NIIMAQ服务器的版本跟主机PC和RT目标设备是不同的。为保证通信正常NII MAQ服…

FPGA project : flash_read

实验目标&#xff1a; flash的普通读指令&#xff0c;在指定地址开始读。可以更改地址与读的数据个数。 先发送读指令扇区地址页地址字节地址。 然后读数据。再把读到的串行数据转化为8bit的数据&#xff0c;存入fifo。 然后读出FIFO中数据&#xff0c;通过uart_tx模块发送…

一行代码优化 pdfjs 加载大文件的pdf 速度

目录 介绍问题分析解决结束 介绍 先简单介绍下pdfjs 怎么 去加载pdf文件 import * as PDFJS from pdfjs-dist/legacy/build/pdf PDFJS.GlobalWorkerOptions.workerSrc require(pdfjs-dist/legacy/build/pdf.worker.entry.js)// blobUrl container指 dom 承载pdf 的容器 expo…

4年软件测试,突破不了20K,太卷了。。。

先说一个插曲&#xff1a;上个月我有同学在深圳被裁员了&#xff0c;和我一样都是软件测试&#xff0c;不过他是平安外包&#xff0c;所以整个组都撤了&#xff0c;他工资和我差不多都是14K。 现在IT互联网已经比较寒冬&#xff0c;特别是软件测试&#xff0c;裁员先裁测试&am…

IDEA 修改插件安装位置

不说假话&#xff0c;一定要看到最后&#xff0c;不然你以为我为什么要自己总结&#xff01;&#xff01;&#xff01; IDEA 修改插件安装位置 前言步骤 前言 IDEA 默认的配置文件均安装在C盘&#xff0c;使用时间长会生成很多文件&#xff0c;这些文件会占用挤兑C盘空间&…

2023年中国合同能源管理行业研究报告

第一章 行业概况 1.1 定义及分类 合同能源管理 (Energy Performance Contracting, EPC) 是当前能源行业中一个重要的概念&#xff0c;它构建了一个桥梁&#xff0c;将节能服务公司 (Energy Management Company, EMCo) 与用能单位紧密联系在一起。通过特定的契约形式&#xff…

解决ERROR: No query specified的错误以及\G 和 \g 的区别

文章目录 1. 复现错误2. 分析错误3. 解决问题4. \G和\g的区别 1. 复现错误 今天使用powershell连接数据库后&#xff0c;执行如下SQL语句&#xff1a; mysql> select * from student where id 39 \G;虽然成功查询除了数据&#xff0c;但报出如下错误的信息&#xff1a; my…

openGauss学习笔记-98 openGauss 数据库管理-管理数据库安全-客户端接入认证之配置客户端接入认证

文章目录 openGauss学习笔记-98 openGauss 数据库管理-管理数据库安全-客户端接入认证之配置客户端接入认证98.1 背景信息98.2 操作步骤98.3 异常处理98.4 示例 openGauss学习笔记-98 openGauss 数据库管理-管理数据库安全-客户端接入认证之配置客户端接入认证 98.1 背景信息 …

用 docker 创建 jmeter 容器, 实现性能测试,该如何下手?

用 docker 创建 jmeter 容器, 实现性能测试 我们都知道&#xff0c;jmeter可以做接口测试&#xff0c;也可以用于性能测试&#xff0c;现在企业中性能测试也大多使用jmeter。docker是最近这些年流行起来的容器部署工具&#xff0c;可以创建一个容器&#xff0c;然后把项目放到…

开源数据库MySQL 8.0 OCP认证精讲视频、环境和题库 之三 选项、变量

选项文件&#xff1a;默认/etc/my.cnf 可以通过以下选项&#xff0c;指定选项文件&#xff1a; -defaults-file&#xff1a;指定选项文件 例如:mysql--defaults-file/etc/my.cnf -no-defaults&#xff1a;不读任何选项文件&#xff0c;所有选项需要在命令行中指定 -defaults-ex…

在Vue+Ts+Vite项目中如何配置别名指向不同的目录并引用

在VueTsVite项目中如何配置别名指向不同的目录并引用 vite.config.ts配置如下&#xff1a;tsconfig.json中需要配置baseUrl和paths,如下所示&#xff1a;项目中直接引入案例&#xff1a; vite.config.ts配置如下&#xff1a; import { defineConfig, AliasOptions } from vite…

FPGA project : flash_secter_erase

flash的指定扇区擦除实验。 先发写指令&#xff0c;再进入写锁存周期等待500ns&#xff0c;进入写扇区擦除指令&#xff0c;然后写扇区地址&#xff0c;页地址&#xff0c;字节地址。即可完成扇区擦除。 模块框图&#xff1a; 时序图&#xff1a; 代码&#xff1a; module…