【1++的C++初阶】之模板(二)

news2025/1/10 3:11:17

👍作者主页:进击的1++
🤩 专栏链接:【1++的C++初阶】

文章目录

  • 一,非类型模板参数
  • 二,模板特化
  • 三,模板分离编译

一,非类型模板参数

模板参数分为类类型模板参数与非类型模板参数。
类类型形参:出现在模板参数列表中,跟在class或typenam的后面的参数类型。
非类型形参:就是用一个常量作为模板的一个参数,在模板中可将该参数当成常量来使用。要注意的是:此常量必须为整型。
例:

template<class T,size_t N=100>
	class Array
	{
	public:
		void Print()
		{
			cout << "print" << endl;
		}
	private:
		T arr[N];
	 
	};

在这里插入图片描述

二,模板特化

模板特化有函数模板特化和类模板特化。
函数模板特化:
我们先来看代码:

namespace hyp
{
	template<class T1, class T2>
	bool less(T1& a, T2& b)
	{
		return a < b;
	}
	
	class Date
	{
	public:

		Date(int year, int month, int day)
			:_year(year)
			,_month(month)
			,_day(day)
		{}

			bool operator<(const Date& d)const
		{
			if (_year < d._year)
			{
				return true;
			}
			else if (_year == d._year)
			{
				if (_month < d._month)
				{
					return true;
				}
				else if (_month == d._month)
				{
					if (_day < d._day)
					{
						return true;
					}
					else
						return false;
				}
				else
					return false;
			}
			else
				return false;

		}
		void Print()
		{
			cout << "print" << endl;
		}

	private:
		int _year;
		int _month;
		int _day;

	};

}

	int main()
	{
		hyp::Date a1(2023, 7, 25);
		hyp::Date a2(2023, 7, 4);
		hyp::Date a3(2023, 7, 16);
		hyp::Date* p1 = &a1;
		hyp::Date* p3 = &a3;
		hyp::Date* p2 = &a2;

		cout << hyp::less(a1, a2);
		cout << hyp::less(p3, p2);

		return 0;
	}

在这里插入图片描述
当我们要进行某些特殊的比较时就会发生以上这种情况—>当我们想通过指向对象的指针比较日期大小时,结果就会有问题,为了解决这种问题,就有了模板特化。
解决上述问题,我们有如下代码:

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

	template<>
	bool less<Date*>(Date*& a, Date*& b)
	{
		return *a < *b;
	}

在这里插入图片描述
类模板特化:
类模板特化又有:全特化与偏特化。
全特化:
全特化即将模板参数列表中的所有参数都确定化。
我们直接来看代码:

template<class T1, class T2>
	class Date
	{
	public:
		void Print()
		{
			cout << "template<class T1,class T2>" << endl;
		}
	private:
		T1 a;
		T2 b;

	};

	template<>
	class Date<int,char>
	{
	public:
		void Print()
		{
			cout << "template<int,char>" << endl;
		}
	private:
		int a;
		char b;

	};

}

	int main()
	{
		hyp::Date<int, int> d1;
		d1.Print();
		hyp::Date<int, char> d2;
		d2.Print();
		hyp::Date<double, char> d3;
		d3.Print();
		return 0}

在这里插入图片描述

偏特化:
偏特化即对模板参数进一步进行条件限制的特化版本。
其有两种表现方式,先来看第一种:

template<class T1, class T2>
	class Date
	{
	public:
		void Print()
		{
			cout << "template<class T1,class T2>" << endl;
		}
	private:
		T1 a;
		T2 b;

	};

	template<class T1>
	class Date<T1,char>
	{
	public:
		void Print()
		{
			cout << "template<T1,char>" << endl;
		}
	private:
		T1 a;
		char b;

	};

在这里插入图片描述
在上述代码中,我们将第二个参数特化为char。
这种表现方式,我们叫做部分特化。
接下来来看第二种:

template<class T1, class T2>
	class Date
	{
	public:
		void Print()
		{
			cout << "template<class T1,class T2>" << endl;
		}
	private:
		T1 a;
		T2 b;

	};

	template<class T1,class T2>
	class Date<T1*,T2*>
	{
	public:
		void Print()
		{
			cout << "template<T1*,T2*>" << endl;
		}
	private:
		T1 a;
		T2 b;

	};

在这里插入图片描述
此种偏特化,对模板参数进行了更进一步的限制。

三,模板分离编译

我们假设有以下场景
在这里插入图片描述

在这里插入图片描述
当我们运行时,会发现链接错误。这是为什么呢?
在进行预处理时,我们的头文件会展开,在编译时,stu.c文件中的func先会去找有没有这个函数,在预处理阶段,头文件已经在我们的stu.c中展开,因此编译器就认为我们有这个函数,所以会根据某中规则形成符号记录在符号表中。而在func.c文件中编译器没有看到对模板函数的实例化,因此不会产生具体的func函数。所以在链接阶段时,我们在符号表中找不到对应的func函数,因此就会发生链接错误。

解决办法就是将函数的声明与定义放在一起,或者是模板定义的位置显式实例化,还可以使用函数的特化。

template<class T>
int func(T a)
{
	return 0;
}
template<>
int func<int>(int a)
{
	return 0;
}

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

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

相关文章

【雕爷学编程】Arduino动手做(167)---MG996R金属齿轮舵机2

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

苹果“空间音频导航”专利曝光,提供导航指引,跟声音走就对啦?

近日&#xff0c;苹果公司成功申请一项专利&#xff0c;该专利名为“空间音频导航”&#xff0c;该专利详细说明了如何利用双耳音频设备&#xff08;AirPods或Apple Vision Pro&#xff09;为用户提供导航指引。 “空间音频导航”是一种模拟声音来源方向和距离的技术&#xff0…

STM32MP157驱动开发——按键驱动(POLL 机制)

文章目录 “POLL ”机制&#xff1a;APP执行过程驱动使用的函数应用使用的函数pollfd结构体poll函数事件类型实现原理 poll方式的按键驱动程序(stm32mp157)gpio_key_drv.cbutton_test.cMakefile修改设备树文件编译测试 “POLL ”机制&#xff1a; 使用休眠-唤醒的方式等待某个…

c# Outlook检索设定问题

基于c# 设定outlook约会予定&#xff0c;时间格式是YYYY-MM-DD HH:mm 的情报。 问题发生&#xff1a; 根据开始时间&#xff08;2023/01/01 7:00&#xff09;条件查询该时间是否存在outlook信息时&#xff0c;明明存在一条数据&#xff0c;就是查询不出来数据 c#代码 Strin…

单源最短路的扩展应用

AcWing 1137. 选择最佳线路 有一天&#xff0c;琪琪想乘坐公交车去拜访她的一位朋友。 由于琪琪非常容易晕车&#xff0c;所以她想尽快到达朋友家。 现在给定你一张城市交通路线图&#xff0c;上面包含城市的公交站台以及公交线路的具体分布。 已知城市中共包含 n 个车站…

解决 Visual Studio Code 编译器代码自动格式化

首先找到.vscode下的settings.json配置文件 将vue3snippets.enable-compile-vue-file-on-did-save-code更改为false

多个HttpSecurity配置(局部AuthenticationManager)

前言 项目用的ruoyi的扩展版本(ts版本)&#xff0c;如果有缺失类&#xff0c;可以自行下载或补充------》个人理解 实现多端token&#xff0c;多端httpSecurity&#xff0c;并且相互隔离&#xff08;局部AuthenticationManager管理认证及授权&#xff09; 在最近的项目中遇到一…

[元带你学: eMMC协议 28] eMMC 上电时序 | eMMC 上电指南

依JEDEC eMMC及经验辛苦整理,原创保护,禁止转载。 专栏 《元带你学:eMMC协议》 内容摘要 全文 1500 字, 主要内容 eMMC 上电规范 和 eMMC 上电指南, 这部分内容偏向电气特性,如果不是硬件的同学只要特别浅的了解, 一带而过。 eMMC 上电规范 eMMC 电压 VCCQ指的是接口…

min_free_kbytes

转自&#xff1a;技术分享 | MemAvailable 是怎么计算的-腾讯云开发者社区-腾讯云 背景 前两天安装 OceanBase 时遇到一个小问题&#xff1a; 很明显&#xff0c;安装OB时要求服务器可用内存至少 8G&#xff0c;不达标就无法安装。为了凑这3台10G内存的服务器我已经费了不少劲…

springMVC快速入门

springMVC快速入门 简介 MVC是一种软件架构的思想&#xff0c;将软件按照模型、视图、控制器类划分。 M(model)&#xff1a;模型层&#xff0c;指工程中的javaBean,作用是处理数据 javaBean分为两类&#xff1a; 一类称为实体类Bean&#xff08;专门存储业务数据&#xff0c;如…

unity 控制text根据字数自动扩展大小,并扩展UI背景

需求&#xff1a;文字内容位置保持不变&#xff0c;向下增加&#xff0c;背景框随之同步扩展。 1.UGUI 九宫格 拉伸 对背景框图片资源处理&#xff0c;避免图片拉伸。 (10条消息) unity UGUI 九宫格 拉伸_unity九宫格拉伸_野区捕龙为宠的博客-CSDN博客 2.背景框添加组件 3.…

Linux 学习记录55(ARM篇)

Linux 学习记录55(ARM篇) 本文目录 Linux 学习记录55(ARM篇)一、使用C语言封装GPIO函数1. 封装GPIO组寄存器2. 封装GPIO模式以及相关配置3. 封装GPIO初始化结构体4. 使用自己的封装配置GPIO 一、使用C语言封装GPIO函数 1. 封装GPIO组寄存器 #define GPIOA ((GP…

断路器分合闸线圈低电压试验

试验目的 断路器的分、 合闸线圈动作电压是保证断路器有效进行分合闸操作的一项重要参 数, 其分、 合闸电压的大小应符合规程要求。 分闸线圈的最低可靠动作值应在额定电 压的 30% ~ 65% , 合闸线圈的最低可靠动作值应在额定电压的 30% ~ 85% , 才能保证 断路器有效进行分合闸…

代码随想录算法训练营第二十二天 | 读PDF复习环节2

读PDF复习环节2 本博客的内容只是做一个大概的记录&#xff0c;整个PDF看下来&#xff0c;内容上是不如代码随想录网站上的文章全面的&#xff0c;并且PDF中有些地方的描述&#xff0c;是很让我疑惑的&#xff0c;在困扰我很久后&#xff0c;无意间发现&#xff0c;其网站上的讲…

vue3中使用wavesurfer插件 动态生成id

需求最终实现的是对话这种&#xff0c;音频文字的对话 使用方法&#xff1a; npm install wavesurfer.js --save官方文档&#xff1a; https://wavesurfer-js.org/ 参数&#xff0c;方法可以去文档查看 直接放封装组件代码 开发背景vue3ts WaveSurfer.vue <template&…

Java学习笔记----Day11(多线程)

多线程 1. 进程、线程2. 实现线程的三种方式3. 线程的生命周期4. 线程里常用的方法5. 线程的调度&#xff08;了解&#xff09;6. 多线程并发环境下&#xff0c;数据的安全问题7. Java三大变量&#xff08;线程同步机制synchronized&#xff09;【重要的内容】8. 死锁9. 开发中…

【正点原子H750MiniPro H750】按键以及时钟

文章目录 前言1.CubeMx的配置步骤1.配置RCC2.配置按键IO口 3.测试代码 总结 前言 H750的最高主频可以达到480Mhz但是一开始在CubeMx配置过程中发现主频达到480Mhz时会报错&#xff0c;以下将会介绍解决办法以及按键移植。 1.CubeMx的配置步骤 1.配置RCC 完成上述步骤配置时钟…

【Ajax】笔记-Axios与函数发送AJAX请求

Axios 和 Ajax 的区别 1、Axios是一个基于Promise的HTTP库&#xff0c;而Ajax是对原生XHR的封装&#xff1b; 2、Ajax技术实现了局部数据的刷新&#xff0c;而Axios实现了对ajax的封装。 优缺点&#xff1a; ajax&#xff1a; 本身是针对MVC的编程,不符合现在前端MVVM的浪潮 基…

小程序 user agent stylesheet 覆盖了page下wxss背景色

如下图&#xff1a; login页面的page下的背景色&#xff0c;被&#xff1a;user agent stylesheet覆盖。 分析与解决&#xff1a; 1、user agent stylesheet是浏览器默认样式表&#xff0c;是浏览器默认样式。 2、不同浏览器的默认样式不同个&#xff0c;甚至同种浏览器不同版…

Linux笔记——rpm与yum下载软件命令介绍

系列文章目录 Linux笔记——进程管理Linux笔记——进程管理与网络监控技术讲解Linux笔记——进程管理 Linux笔记——管道相关命令以及shell编程 Linux笔记——磁盘进行分区与挂载介绍 文章目录 系列文章目录 前言 一 RPM介绍 1.1 RPM简单介绍 1.2 RPM命令语法 1.2.1 …