模板进阶(仿函数,特化等介绍)
非类型模板参数
模板参数有类型形参和非类型形参;
类型形参:使用typename或者class修饰的参数类型名称
非类型形参:一个普通常量作为模板参数形参,不能为浮点数,字符类型以及类对象;
#include<iostream>
using namespace std;template<class T, size_t N = 64>
class test {private:T data = 10;
public:void print(){cout << data << endl << N << endl;}};int main()
{test<int> a;a.print();return 0;
}
上面的代码中,T就是典型的类型形参,N为非类型形参,这个N我们在类函数成员中可以直接使用
模板的特化
我们都知道,使用模板能够很方便的做出能够适应各种场景的函数,比如比较大小,加减法等函数:
template<class T>
bool Less(T a, T b)
{return a < b;
}int main()
{cout << Less(1, 2) << endl;Date a(2022, 7, 8);Date b(2022, 7, 7);cout << Less(a, b)<< endl;return 0;
}

比如这样,就能够比较 int,double 之类的类型,但是有时候我们的类型可能无法满足我们的需求
比如:

我们需要比较的是Date类中的日期大小,但是我们传 Date* 类型进行比较时;
却发现比较的结果实际上是按照地址的大小来进行比较的。
对于这种情况,就需要我们的函数模板的特化出场了;
函数模板特化的步骤
1.有一个基础的函数模板
2.有一个template关键字,后面跟着一个空的<>
3.函数名后跟着一个<>,尖括号中指定需要特化的类型
4.函数形参表必须和模板函数的基础参数类型完全相同,否则会报错
比如上面的 Less 模板函数如何特化?
template<class T>
bool Less(T a, T b)
{return a < b;
}template<>
bool Less<Date*>(Date* a, Date* b)
{return *a < *b;
}
我们对比基础函数模板,我们发现,特化的函数模板不仅template后面跟着空的 <> ,而且函数名后还有一个 <> ,并且里面有特化的类型,且形参名都是相同的;
这样我们就能够顺利比较 Date* 类型的参数了;

即然有函数的模板特化,那么就有类的模板特化
类的模板特化和函数的模板特化的规则类似。
类的模板特化
类的模板特化分为两种——全特化和偏特化;
我们先了解简单的全特化
全特化
template<class T1,class T2>
class Test {
public:Test(){cout << "Test(T1,T2)" << endl;}private:T1 a;T2 b;
};template<>
class Test<char, char> {
public:Test(){cout << "Test(char,char)" << endl;}
};int main()
{Test<int, int> t1;Test<char, char> t2;return 0;
}

全特化和函数特化一样,需要有基础的类模板,并且还得有其他一些条件才能实现特化;
若是创建的类对象和特化的类型一致,就会使用特化的类;
偏特化
所谓偏特化就是指这个类并非全都是指定一个类型,而是有特化有没特化的。
template<class T1>
class Test<T1, int> {
public:Test(){cout << "Test(T1,int)" << endl;}
};
就比如这个,我们指定特化第二个参数是 int 类型的,因此若是后面使用 int 类型当做第二个模板参数,就会使用这个类型;
int main()
{Test<int, int> t1;Test<char, char> t2;Test<char, int> t3;return 0;
}

而偏特化里面还有一个更特殊的——针对模板参数进一步条件限制设计出来的特化版本
这个和普通的偏特化不同,它的规则不同,我们先来看看实例;
template<class T1,class T2>
class Test<T1&, T2&> {
public:Test(){cout << "Test(T1&,T2&)" << endl;}
};
我们发现,它的template后不是跟着空 <>,其内部有正常的模板参数;
但是类名后面跟着不同指定特化的类型。
这就是进一步限制条件的特化版本。
模板特化应用示例
比如我们使用一个仿函数用来比较函数时,我们有时单纯靠模板无法满足需求,就需要特化版本来满足需求;
template<class T>
class Less {bool operator()(const T&x,const T& y)const {return x < y;}
比如这个,我们比较普通的类型无所谓,但是若是比较的是 Date* 的类型时,就会比较地址大小导致出错,因此需要特化。
template<>
class Less<Date*>
{bool operator()(const Date* x, const Date* y){return *x < *y;}
};
模板分离编译
当我们写模板类的时候需要注意一个点——模板类不能分离编译。
什么是分离编译?就是指模板函数或者模板类的函数声明和定义分别在不同的文件。
而模板函数和模板类的声明和定义在不同位置会导致出错。
这是因为编译器对于每个源文件都是独立编译的,若是分离编译则会导致源文件之间没有交互,导致对应的模板没有实例化,从而出错。
具体解决办法就是将声明定义放在一起,从而避免出错。
相关文章:
模板进阶(仿函数,特化等介绍)
非类型模板参数 模板参数有类型形参和非类型形参; 类型形参:使用typename或者class修饰的参数类型名称 非类型形参:一个普通常量作为模板参数形参,不能为浮点数,字符类型以及类对象; #include<iostrea…...
Beats:在 Docker 中同时部署 Metricbeat 和 Elasticsearch
在本教程中,我们将部署一个 metricbeat 来监控正在运行的容器的健康状况和系统指标。 为什么需要监控,为什么需要 Metricbeat? 一个常见的问题,但很少有人回答。 首先,无论我们部署的是 docker 容器还是老式的金属箱&…...
编码技巧——Redis Pipeline
本文介绍Redis pipeline相关的知识点及代码示例,包括Redis客户端-服务端的一次完整的网络请求、pipeline与client执行多命令的区别、pipeline与Redis"事务"、pipeline的使用代码示例; pipeline与client执行多命令的区别 Redis是一种基于客户…...
ArcGIS制图技巧:制图入门与点、线、面状符号制作
目的: 1、了解地图制作目的; 2、了解在ArcMap平台中制作地图大致过程。 3、掌握地形图生成的操作; 4、掌握地形图的正确输出方法。 5、理解点状符号、线状符号、面状符号的基本概念; 6、理解地形点状符号、线状符号、面状符…...
Java基础 关于字典数据维护接口设计
开发环境 Eclipse2022JDK1.8 目录 1. 概述 2. 实现步骤 2.1 定义通用接口 2.2 定义实体类 2.3 接口扩展 2.4 接口实现 2.5 功能测试 3. 结语 1. 概述 每一个信息系统或多或少都带有一些数据字典,在维护上,基本上分为增删改查,也就是对数据…...
从零开始学架构——复杂度来源
复杂度来源——高性能 对性能孜孜不倦的追求是整个人类技术不断发展的根本驱动力。例如计算机,从电子管计算机到晶体管计算机再到集成电路计算机,运算性能从每秒几次提升到每秒几亿次。但伴随性能越来越高,相应的方法和系统复杂度也是越来越高。现代的计算机CPU集成…...
什么时候需要分表分库?
在当今互联网时代,海量数据基本上是每一个成熟产品的共性,特别是在移动互联网产品中,几乎每天都在产生数据,例如,商城的订单表、支付系统的交易明细以及游戏中的战报等等。对于一个日活用户在百万数量级的商城来说&…...
冰刃杀毒工具使用实验(29)
实验目的 (1)学习冰刃的基本功能; (2)掌握冰刃的基本使用方法;预备知识 windows操作系统的基本知识,例如:进程、网络、服务和文件等的了解。 冰刃是一款广受好评的ARK工…...
聊聊图像分割的DICE和IOU指标
目录 1. 介绍 2. dice 和 iou 的联系 3. 代码实现 3.1 dice 3.2 iou 3.3 test 3.4 dice 和 iou 的关系曲线 4. 代码 1. 介绍 dice 和 iou 都是衡量两个集合之间相似性的度量 dice计算公式: iou计算公式: iou的集合理解: iou 其实就…...
软件设计师教程(十)计算机系统知识-结构化开发
软件设计师教程 软件设计师教程(一)计算机系统知识-计算机系统基础知识 软件设计师教程(二)计算机系统知识-计算机体系结构 软件设计师教程(三)计算机系统知识-计算机体系结构 软件设计师教程(…...
链表OJ之 快慢指针法总结
欢迎来到 Claffic 的博客 💞💞💞 前言: 快慢指针指的是每次指针移动的步长,是解决链表相关的题目的一大利器,下面我将以例题的形式讲解快慢指针法。 目录 一. 链表的中间结点 思路: 代码实…...
C++STL详解(五)——list的介绍与使用
文章目录list的介绍list的使用list的定义方法list迭代器失效问题list插入和删除inserteraselist迭代器的使用begin,end 和 rbegin,rendlist元素访问front 和 backlist容量控制与数据清理resizeclearlist操作函数spliceremove 和 remove_ifuniquemergerev…...
进程和进程的调度
今天,为大家带来进程和进程的调度的学习 1.认识计算机 2.什么是操作系统 3.什么是进程 4.进程管理 5.进程的属性 6.进程的调度 7.进程调度的过程 8.内存分配 1.认识计算机 计算机的组成有五大部分 1.CPU(是计算机的大脑,负责逻辑运算和控制) 2.内存 3.外存 4.输入…...
TypeScript 深度剖析:TypeScript 的理解?与 JavaScript 的区别?
一、是什么 TypeScript 是 JavaScript 的类型的超集,支持ES6语法,支持面向对象编程的概念,如类、接口、继承、泛型等 超集,不得不说另外一个概念,子集,怎么理解这两个呢,举个例子,如…...
美颜SDK关键技术讲解——人脸识别与人脸美化
拍摄,自从智能手机普及之后就已经不再是小众爱好,使用手机拍摄记录生活几乎成了人们的日常。在巨量的需求下,美颜工具、美颜SDK已经被广泛应用于各大视频拍摄平台。虽然经常听到美颜SDK,但是大多数人并不了解它,下文小…...
Linux下C/C++ 网络扫描(主机扫描技术)
主机扫描是网络扫描的基础,通过对目标网络中主机IP地址的扫描,从一堆主机中扫描出存活的主机,然后以他们为目标进行后续的攻击。一般会借助于ICMP、TCP、UDP等协议的工作机制,检查打开的进程,开放的端口号等等。 主机…...
无法将“vue-cli-service”项识别为 cmdlet、函数、脚本文件或不是内部命令的原因和解决方案
经常有小伙伴问我说,为什么我们在开发vue项目的时候,需要在package.json的script对象中,去设置命令启动项目,而不是直接的通过"vue-cli-service serve"命令去把项目跑起来。带着这些疑问,小生在此总结了以下…...
逆流程 场景下 处理状态机变化的方案
背景: 针对某些业务场景下,存在逆流程。 比如场景的场景 正向流程如,发起某项申请->对某项申请进行审批。(审批为通过/驳回)。这样这个工作流程就算到最终态。 常见的状态机如, 申请未提交࿰…...
【剧前爆米花--爪哇岛寻宝】Java实现无头单向非循环链表和无头双向链表与相关题目
作者:困了电视剧 专栏:《数据结构--Java》 文章分布:这是关于数据结构链表的文章,包含了自己的无头单向非循环链表和无头双向链表实现简单实现,和相关题目,想对你有所帮助。 目录 无头单向非循环链表实现 …...
学习MvvmLight工具
最近学习了一下MvvmLight,觉得有些功能还是挺有特色的,所以记录一下 首先新建也给WPF程序 然后在Nuget里面安装MvvmLightLib 包,安装上面那个也可以,但是安装上面那个会自动在代码里面添加一些MvvmLight的demo ,安装M…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
路由基础-路由表
本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中,往往存在多个不同的IP网段,数据在不同的IP网段之间交互是需要借助三层设备的,这些设备具备路由能力,能够实现数据的跨网段转发。 路由是数据通信网络中最基…...
