C++模板的特化

news2024/9/23 0:35:00

目录

一、模板特化概念

二、函数模板特化

三、类模板特化

1.全特化

2.偏特化

3.总结

4.类模板特化实例应用


一、模板特化概念

函数模板和类模板都有特化:

通常情况下使用模板可以实现一些与类型无关的代码,但一些特殊类型可能会出错,因此需要特殊化处理,这就是模板的特化

代码演示:

当函数模板参数类型为Date*时,很明显会发生错误,因为函数模板中是通过地址大小来判断日期大小的(日期大小与其地址无关),很显然这是错误的。

// 函数模板 -- 参数匹配
template<class T>
bool Less(T left, T right)
{
	return left < right;
}
int main()
{
	cout << Less(1, 2) << endl; // 可以比较,结果正确

	Date d1(2022, 7, 7); Date d2(2022, 7, 8);
	cout << Less(d1, d2) << endl; // 可以比较,结果正确

	Date* p1 = &d1; Date* p2 = &d2;
	cout << Less(p1, p2) << endl; // 可以比较,结果错误
	return 0;
}

二、函数模板特化

// 函数模板 -- 参数匹配
template<class T>
bool Less(T left, T right)
{
	return left < right;
}
//对Less函数模板进行特化
template<>
bool Less(Date* left, Date* right)
{
	return *left < *right;
}
int main()
{
	cout << Less(1, 2) << endl; // 可以比较,结果正确

	Date d1(2022, 7, 7); Date d2(2022, 7, 8);
	cout << Less(d1, d2) << endl; // 可以比较,结果正确

	Date* p1 = &d1; Date* p2 = &d2;
	cout << Less(p1, p2) << endl; // 可以比较,结果错误
	return 0;
}

实践中,并不推荐使用函数模板的特化。更推荐使用函数重载:遇到不支持的类型,可以直接将该函数给出,更加简洁明了,可读性高(对于一些参数类型复杂的函数模板,特化时容易出错) 

// 函数模板 -- 参数匹配
template<class T>
bool Less(T left, T right)
{
	return left < right;
}

//Less函数重载
bool Less(Date* left, Date* right)
{
	return *left < *right;
}

int main()
{
	cout << Less(1, 2) << endl; // 可以比较,结果正确

	Date d1(2022, 7, 7); Date d2(2022, 7, 8);
	cout << Less(d1, d2) << endl; // 可以比较,结果正确

	Date* p1 = &d1; Date* p2 = &d2;
	cout << Less(p1, p2) << endl; // 可以比较,结果错误
	return 0;
}

三、类模板特化

1.全特化

全特化就是将模板参数列表中的所有参数都确定好

template<class T1, class T2>
class Data
{
public:
	Data() { cout << "Data<T1, T2>" << endl; }
private:
	T1 _d1;
	T2 _d2;
};

template<>
class Data<int, char>
{
public:
	Data() { cout << "Data<int, char>" << endl; }
private:
	int _d1;
	char _d2;
};
int main()
{
	Data<int, int> d1;
	Data<int, char> d2;
	return 0;
}

2.偏特化

偏特化:特化部分参数 或 对模板参数进行条件限制

特化部分参数:

template<class T1, class T2>
class Data
{
public:
	Data() { cout << "Data<T1, T2>" << endl; }
private:
	T1 _d1;
	T2 _d2;
};

//偏特化:特化部分参数
template<class T1>
class Data<T1, int>
{
public:
	Data() { cout << "Data<T1, int>" << endl; }
private:
	T1 _d1;
	int _d2;
};

对模板参数进行条件限制:

//将模板参数偏特化成指针类型
template<class T1, class T2>
class Data<T1*, T2*>
{
public:
	Data() { cout << "Data<T1*, T2*>" << endl; }
private:
	T1 _d1;
	T2 _d2;
};

//将模板参数偏特化成指针类型
template<class T1, class T2>
class Data<T1&, T2&>
{
public:
	Data() { cout << "Data<T1&, T2&>" << endl; }
private:
	T1 _d1;
	T2 _d2;
};
3.总结
int main()
{
	Data<double, int> d1; // 调用特化的int版本
	Data<int, double> d2; // 调用基础的模板 
	Data<int*, int*> d3; // 调用特化的指针版本
	Data<int&, int&> d4; // 调用特化的指针版本
	return 0;
}
4.类模板特化实例应用
template<class T>
struct Less {
	bool operator()(const T& x, const T& y) const
	{
		return x < y;
	}
};

//仿函数类偏特化
template<class T>
struct Less<T*>
{
	bool operator()(const T* x, const T* y) const
	{
		return *x < *y;
	}
};

//仿函数类偏特化(这种方式也行)
//template<>
//struct Less<Date*>
//{
//	bool operator()(Date* x, Date *y) const
//	{
//		return *x < *y;
//	}
//};

void test()
{

	Date d1(2024, 8, 16);
	Date d2(2024, 8, 17);
	Date d3(2024, 8, 18);
	vector<Date> v1;
	v1.push_back(d1);
	v1.push_back(d2);
	v1.push_back(d3);
	sort(v1.begin(), v1.end(), Less<Date>());// 可以直接排序,结果是日期升序
	for (auto& e : v1)
		cout << e << " ";
	cout << endl;

	vector<Date*> v2;
	v2.push_back(&d1);
	v2.push_back(&d2);
	v2.push_back(&d3);
    // 如果没有偏特化
    // 可以直接排序,结果错误日期还不是升序,而v2中放的地址是升序
    // 此处需要在排序过程中,让sort比较v2中存放地址指向的日期对象
    // 但是走Less模板,sort在排序时实际比较的是v2中指针的地址,因此无法达到预期
    // 
    // 偏特化之后,得到正确排序结果
	sort(v2.begin(), v2.end(), Less<Date*>());
    

	for (auto& e : v2)
		cout << *e << " ";
	cout << endl;
}

int main()
{
	test();
	return 0;
}

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

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

相关文章

报错:Can‘t find Python executable “python“, you can set the PYTHON env variable

将项目导入vscode,执行npm install命令后&#xff0c;报错了&#xff0c;报错的信息是node-sass安装失败&#xff0c;同时提示需要python环境的错误信息&#xff0c;这是因为安装node-sass失败了&#xff0c;而node-sass依赖于Python环境。 1.报错&#xff1a;Cant find Python…

基于Hadoop的微博社交媒体用户大数据分析【海量数据】

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍数据集展示Hadoop脚本文件可视化展示每文一语 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 项目介绍 本项目基于hadoop的社交媒体用户进行大数据…

把照片制作成精美的仿真电子相册

​在这个数字化时代&#xff0c;我们拍摄的照片越来越多&#xff0c;但往往缺乏一个合适的方式来展示和保存这些珍贵的回忆。今天&#xff0c;我将向大家介绍如何将你的照片制作成一个精美的仿真电子相册&#xff0c;让你的回忆更加生动和持久。 第一步&#xff1a;选择合适的照…

FreeRTOS 3

一&#xff0c;信号量 有时候任务之间传递的只是一个标致&#xff0c;让进程之间同步&#xff0c;会对一个共享资源的互斥性访问&#xff0c;这时候就可以用信号量和互斥量。 1&#xff0c;二值信号量 2&#xff0c;计数信号量 3&#xff0c;互斥量 3.1&#xff0c;差别 4&…

Orangepi 5 Pro(香橙派5pro)部署yolov5

前言 香橙派内置了6T算力的NPU&#xff0c;想着可以跑一下yolov5&#xff0c;看看香橙派的速度如何。 在开始部署之前&#xff0c;需要具备一定的linux技能——vim、linux常见指令、conda等等。如果没有这些技能的话&#xff0c;做下去会有一定的难度&#xff0c;可以先看几遍了…

19.实现一个算法实现删除链表中倒数第 n 个结点

19. Remove Nth Node From End of List 题目 Given the head of a linked list, remove the nth node from the end of the list and return its head. Follow up: Could you do this in one pass? Example 1: Input: head = [1,2,3,4,5], n = 2 Output: [1,2,3,5]Example…

蚂蚁AL1 15.6T 创新科技的新典范

● 哈希率&#xff1a;算力达到15.6T&#xff08;相当于15600G&#xff09;&#xff0c;即每秒能够进行15.6万亿次哈希计算&#xff0c;在同类产品中算力较为出色&#xff0c;能提高WA掘效率。 ● 功耗&#xff1a;功耗为3510W&#xff0c;虽然数值看似不低&#xff0c;但结合其…

PythonStudio 控件使用常用方式(二十七)TActionList

PythonStudio是一个极强的开发Python的IDE工具&#xff0c;官网地址是&#xff1a;https://glsite.com/ &#xff0c;在官网可以下载最新版的PythonStudio&#xff0c;同时&#xff0c;在使用PythonStudio时&#xff0c;它也能及时为用户升到最新版本。它使用的是Delphi的控件&…

Python爬虫技术与K-means算法的计算机类招聘信息获取与数据分析

有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 目录 摘要.... 1 Abstract 2 1 引言.... 3 1.1 研究背景... 3 1.2 国内外研究现状... 4 1.3 研究目的... 5 1.4 研究意义... 7 2 关键技术理论介绍... 7 2.1 Python爬虫... 7 2.1 K-means…

消灭星星游戏程序设计【连载十一】——在线程中解决音效卡顿问题

消灭星星游戏程序设计【连载十一】——在线程中解决音效卡顿问题 大家每次都可以在页面中下载本节内容的实现代码&#xff0c;一步一步从简单开始&#xff0c;逐步完成游戏的各种功能&#xff0c;如果大家有任何问题也欢迎留言交流。 游戏整体效果展示&#xff1a; 1、本节要达…

宠物空气净化器哪款好?希喂、有哈宠物空气净化器测评

回想起几年前那个午后&#xff0c;我意外的在路边捡到了两只小猫咪&#xff0c;心中莫名有一份责任感出现&#xff0c;所以没有丝毫犹豫我就决定将它们带回家。捡回家以后&#xff0c;家里确实多了几分温馨&#xff0c;逐渐成为我的精神支柱。小猫的到来&#xff0c;让家的每一…

Mybatis工具类的封装

为什么要进行Mybatis工具类的封装&#xff1f; 每次我们执行数据库操作都需要做以下操作&#xff1a; //读取配置文件InputStream inputStream Resources.getResourceAsStream("mybatis-config.xml");//通过配置文件创建SqlSessionFactorySqlSessionFactory sqlSess…

模板[C++]

目录 1.&#x1f680;泛型编程&#x1f680; 2.&#x1f680;函数模板&#x1f680; 2.1 ✈️函数模板概念✈️ 2.2 ✈️函数模板格式✈️ 2.3✈️函数模板的原理✈️ 2.4 ✈️函数模板的实例化✈️ 2.5 ✈️模板参数的匹配原则✈️ 3.&#x1f680;类模板&#x1f680…

Ubuntu20.4 系统安装后无wifi图标

0. 问题排查 1.检查 BIOS 设置: 有时候&#xff0c;无线网卡可能在 BIOS 中被禁用。重启电脑&#xff0c;进入 BIOS 设置&#xff0c;确保无线网卡选项是启用的。 2.检查硬件开关: 检查您的笔记本电脑是否有物理开关或键盘快捷键来启用或禁用无线网卡。 3.在软件更新中切换…

Codeforces Round 495 (Div. 2) F. Sonya and Bitwise OR(线段树)

原题链接&#xff1a;F. Sonya and Bitwise OR 题目大意&#xff1a; 给出一个长度为 n n n 的数组 a a a&#xff0c;并给出 m m m 次询问以及一个数字 x x x。 每个询问形式如下给出&#xff1a; 1 1 1 i i i y y y &#xff1a;将 a i a_{i} ai​ 位置的值更改为 y…

将2,3,4,5,6,8分别填入算式“口口口X口口口“的“囗“中,怎么填使得算式结果最大。

一、解题思路 将数组元素进行全排列&#xff1a;对整个数组进行全排列&#xff0c;这样我们可以避免手动选择组合、排列剩余元素等步骤。 直接分割排列后的数组&#xff1a;在每一个全排列中&#xff0c;前3个元素和后3个元素自然形成了一个组合和一个剩余元素组合。 计算并…

Linux安装redis和使用redisDesktop连接

目录 Linux安装redis及启动 第一步&#xff1a;下载redis压缩包 第二步&#xff1a;下载gcc-c 第三步&#xff1a;解压redis文件 第四步&#xff1a;进入redis-4.0.0.0目录执行make命令 第五步&#xff1a;安装redis到redis目录 第五步&#xff1a;复制redis.conf配置文件…

电脑开机LOGO修改教程_BIOS启动图片替换方法

准备工具&#xff1a;刷BIOS神器和change logo&#xff0c;打包下载地址&#xff1a;https://download.csdn.net/download/baiseled/89374686 一.打开刷BIOS神器&#xff0c;点击备份BIOS&#xff0c;保存到桌面 二.打开change logo&#xff0c;1.点击load image&#xff0c;选…

11-sentinel利用nacos作持久化

本文介绍sentinel配置数据的持久化方法。由于sentinel官方并没有提供持久化功能&#xff0c;大家在测试过程中也能发现sentinel服务重启后&#xff0c;原来配置的数据就丢了&#xff0c;本文就是来处理这一问题的。 做好心理准备&#xff0c;我们要修改sentinel的源代码&#…

Python 批量修改 Word 文档中图片的大小并居中对齐

Python 批量修改 Word 文档中图片的大小并居中对齐 错过&#xff0c;再遇见可能就难了&#xff01;此时&#xff0c;你是你&#xff0c;我是我&#xff0c;再遇见&#xff0c;可就真的你是你&#xff0c;我是我&#xff0c;没有一丝的牵连纠缠—— !!! 对于已经编辑好的文档一定…