模板进阶:非类型模板参数,特化

一、非类型模板参数

非类型模板参数,就是用一个常量作为 类/函数 的模板参数,在 类/函数 中可以被当成常量使用。

template<class T, size_t N>// N 为一个非类型模板参数
class Stack
{
public:Stack(){_a = new T[N];}
protected:T* _a;
};int main()
{Stack<int, 10> st;// 初始化方式return 0;
}

P.S.

  • 浮点数、类对象、字符串不允许作为非类型模板参数
  • 非类型模板参数必须在编译时就确定结果

二、模板的特化

首先给定一个 Date 类,并完善必要的函数及运算符重载,以便后续介绍相关概念。

	class Date{public:Date(int year, int month, int day):_year(year), _month(month), _day(day){}bool operator<(const Date& d){if (_year < d._year)return true;else if (_year == d._year && _month < d._month)return true;else if (_year == d._year && _month == d._month && _day < d._day)return true;return false;}friend ostream& operator<<(ostream& out, const Date& d);protected:int _year;int _month;int _day;};ostream& operator<<(ostream& out, const Date& d){out << d._year << " " << d._month << " " << d._day << endl;return out;}
2.1 函数模板特化
  • 函数模板的特化,必须建立在一个基础的函数模板上
  • template<> 函数名<特化的参数类型> { //... }
  • 必须要和模板函数的基础参数类型完全相同,否则编译器会各种报错
给出下面的一种情景:比较两个日期的大小关系
template<class T>
bool Less(T a, T b)
{return a < b;
}int main()
{Date d1(2024, 1, 2);Date d2(2024, 3, 12);cout << Less(d1, d2) << endl;Date* p1 = &d1;Date* p2 = &d2;cout << Less(p1, p2) << endl;return 0;
}

Less(d1, d2) 的比较没有问题,而 Less(p1, p2) 的结果则不尽如人意:

默认情况下,Less(p1, p2) 是在比较 p1 和 p2 的指针大小关系。如果想要做到通过指针就能完成对日期大小的比较,则需要对 Date* 类型特化,重载 Less 函数

template<> // 格式
bool Less<Date*>(Date* a, Date* b) 
{return *a < *b;
}// 再次强调:**必须要和模板函数的基础参数类型完全相同**,否则编译器会各种报错
注意:

一般情况函数模板无法实例化出满足要求的函数,我们通常给出具体实现——更简单、方便。

bool Less(Date* a, Date* b)
{return *a < *b; // 直接实现,不走函数模板的特化
}
2.2 类模板的特化
2.2.1 全特化

全特化:将模板参数列表中所有参数都给明

template<class T1, class T2>
class AA
{
public:AA() { cout << "AA<T1, T2>" << endl; }
};// 格式 与 函数模板特化格式类似
template<>
class AA<int, char> // 将模板参数列表中所有参数都给明
{
public:AA() { cout << "AA<int, char>" << endl; }
};int main()
{AA<int, int> a1;AA<int, char> a2;
}
2.2.2 偏特化

偏特化有两种方式:

  • 部分特化:将模板参数列表中的一部分参数特化
template<class T>
class AA<int, T>
{
public:AA() { cout << "AA<int, T>" << endl; }
};
  • 对参数进一步限制
template<class T1, class T2>
class AA<T1&, T2&> 
{
public:AA() { cout << "AA<T1&, T2&>" << endl; }
};template<class T1, class T2>
class AA<T1*, T2*> 
{
public:AA() { cout << "AA<T1*, T2*>" << endl; }
};int main()
{AA<int*, char*> a1;AA<int&, char&> a2;
}
2.2.3 Date* 特化仿函数示例
	template<class T>// 普通版本class ComLess{public:bool operator()(T a, T b){return a < b;}};template<>class ComLess<Date*> // 对于 Date* 类型的特化版本{public:bool operator()(Date* a, Date* b){return *a < *b;}};
int main()
{priority_queue<Date*, vector<Date*>, ComLess<Date*>> pq;pq.push(new Date(2024, 2, 12));pq.push(new Date(2024, 2, 22));pq.push(new Date(2024, 2, 2));while (!pq.empty()){cout << *pq.top() << endl;// pq 的元素是指向Date类的指针// 如果想观察Date 的大小关系,需要对 pq.top() 解引用}return 0;
}

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

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

相关文章

GAMMA数据处理(六)

最近进行Sentinel-1数据处理,需要用到拼接三个iw的命令,找了一下 但是这样大的数据提取进来,处理速度很慢,后面可能要进行研究区的裁剪,除了开始用的方法,直接在生成的burst_tab文件里面修改参数:删去自己不需要的iw,也就是下面说的这种方法 在指导手册上面看到了其他的…

前端接口防止重复请求实现方案

虽然大部分的接口处理我们都是加了loading的&#xff0c;但又不能确保真的是每个接口都加了的&#xff0c;可是如果要一个接口一个接口的排查&#xff0c;那这维护了四五年的系统&#xff0c;成百上千的接口肯定要耗费非常多的精力&#xff0c;根本就是不现实的&#xff0c;所以…

使用OpenCV实现人脸特征点检测与实时表情识别

引言&#xff1a; 本文介绍了如何利用OpenCV库实现人脸特征点检测&#xff0c;并进一步实现实时表情识别的案例。首先&#xff0c;通过OpenCV的Dlib库进行人脸特征点的定位&#xff0c;然后基于特征点的变化来识别不同的表情。这种方法不仅准确度高&#xff0c;而且实时性好&am…

Serverless:无服务器架构的魅力与实践

导语&#xff1a;随着云计算的不断发展&#xff0c;无服务器架构&#xff08;Serverless&#xff09;逐渐成为开发人员关注的焦点。本文将为您深入解析 Serverless 的概念、优势、应用场景以及实践经验&#xff0c;带您领略 Serverless 的魅力&#xff01; 一、Serverless 是什…

打卡学习kubernetes——了解kubernetes组成及架构

目录 1 什么是kubernetes 2 kubernetes组件 3 kubernetes架构 1 什么是kubernetes kubernetes是一个旨在自动部署、扩展和运行应用容器的开源平台。目标是构建一个生态系统&#xff0c;提供组件和工具以减轻在公共和私有云中运行应用程序的负担。 kubernetes是&#xff1a…

deepin23beta中SQLite3数据库安装与使用

SQLite 是一个嵌入式 SQL 数据库引擎&#xff0c;它实现了一个自包含、无服务器、零配置、事务性 SQL 数据库引擎。 SQLite 的代码属于公共领域&#xff0c;因此可以免费用于任何商业或私人目的。 SQLite 是世界上部署最广泛的数据库&#xff0c;其应用程序数量之多&#xff0c…

Linux使用Docker部署Registry结合内网穿透实现公网远程拉取推送镜像

文章目录 1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址 Docker Registry 本地镜像仓库,简单几步结合cpolar内网穿透工具实现远程pull or push (拉取和推送)…

VUE 运行NPM 报错:npm ERR! code CERT_HAS_EXPIRED 解决方案

现象 由于各种原因需要调试一下VUE代码&#xff0c;用Git拉下来运行不了&#xff08;之前是可以正常运行的&#xff09;&#xff0c;报错为&#xff1a;npm ERR! code CERT_HAS_EXPIRED........... 原因 NPM 证书签名过期了 解决方法 第一步&#xff1a;CMD 命令 查看NPM代理源…

【C++ RB树】

文章目录 红黑树红黑树的概念红黑树的性质红黑树节点的定义红黑树的插入代码实现总结 红黑树 AVL树是一颗绝对平衡的二叉搜索树&#xff0c;要求每个节点的左右高度差的绝对值不超过1&#xff0c;这样保证查询时的高效时间复杂度O( l o g 2 N ) log_2 N) log2​N)&#xff0c;…

MySQL锁整理

MySQL锁信息来源 MySQL锁太多&#xff0c;内容太杂。写篇文章记录一下

【C++ 设计模式】策略模式与简单工厂模式的结合

文章目录 前言一、为什么需要策略模式简单工厂模式二、策略模式简单工厂模式实现原理三、UML图四、示例代码总结 前言 在软件设计中&#xff0c;常常会遇到需要根据不同情况选择不同算法或行为的情况。策略模式和简单工厂模式是两种常见的设计模式&#xff0c;它们分别解决了对…

z1-5输入编码器实验

一. 实验内容 1、制作LED计数电路&#xff0c;输入是编号为1~5的5个开关&#xff0c;输出是5个发光二极管&#xff08;LED&#xff09; 点几号开关&#xff0c;就有几个LED发光。 2、制作一个5位输入3位输出的编码器&#xff0c; 输入的第5位为1&#xff0c;输出就是数字5对应…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:ColumnSplit)

将子组件纵向布局&#xff0c;并在每个子组件之间插入一根横向的分割线。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 ColumnSplit通过分割线限制子组件的高度。初始…

SQLiteC/C++接口详细介绍之sqlite3类(三)

快速跳转文章列表&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;二&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;四&#xff09; 6.sqlite3_create_module与sqlite3_create_module_v2函数…

简单了解 vim 编辑器最基础的操作

简单了解 vim 编辑器最基础的操作 vim 这个是 Linux 上自带的一个文本编辑器&#xff0c;使用 vim 就可以更灵活的对文件进行编辑了&#xff08;虽然和记事本的定位差不多,实际上vim的使用要复杂很多&#xff09; 1.打开文件 语法&#xff1a;vim 文件名 示例&#xff1a;…

16.旋转图像

给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&…

ubuntu 安装 infiniband 和 RoCE 驱动

下载驱动程序 驱动程序地址 https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ 安装 安装参考文档 https://docs.nvidia.com/networking/display/mlnxofedv24010331/installing+mlnx_ofed#src-2571322208_InstallingMLNX_OFED-InstallationProced…

BUGKU-WEB cookies

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; 解题思路 看源码看F12&#xff1a;看请求链接看提示&#xff1a;cookies欺骗 相关工具 插件&#xff1a;ModHeader或者hackbarbase64解密 解题步骤 看源码 就是rfrgrggggggoaihegfdiofi48ty598whrefeoia…

构建部署_Jenkins介绍与安装

构建部署_Jenkins介绍与安装 构建部署_Jenkins介绍与安装Jenkins介绍Jenkins安装 构建部署_Jenkins介绍与安装 Jenkins介绍 Jenkins是一个可扩展的持续集成引擎。 持续集成&#xff0c;就是通常所说的CI&#xff08;Continues Integration&#xff09;&#xff0c;可以说是现…

MySQL--深入理解MVCC机制原理

什么是MVCC&#xff1f; MVCC全称 Multi-Version Concurrency Control&#xff0c;即多版本并发控制&#xff0c;维持一个数据的多个版本&#xff0c;主要是为了提升数据库的并发访问性能&#xff0c;用更高性能的方式去处理数据库读写冲突问题&#xff0c;实现无锁并发。 什…