C++——模板的作用2:特例化
目录
模板的形式:
一.模板的多参数应用:
例:
错误使用1:使用不标准的模板形参表
编辑
错误使用2:使用变量作为实参传递给函数模板
二.模板的特例化:
类模板:
针对模板的特化步骤:
类模板的全特化:
类模板的半特化:
半特化的扩展:
三. 模板总结
在之前,我介绍过一篇关于C++模板的作用,它的出现解决了C语言对多种不同类型的但是有着相同作用函数的难题,举个例子:想要作用于两个整型变量的交换,那么使用C语言可以写出整型交换的函数,但是又出现了char型、double型、short型变量的交换,那么就需要再写出这三个类型的交换函数,而这几个函数写出来后唯一的不同点就是返回值和形参的不同,造成了代码的冗余,可读性变差。
模板的形式:
template <模板形参表>
返回值类型 函数体(模板函数形参表)
{
}
而模板的出现使得交换函数只需要写一个就够,极大的缩减了代码,增加了函数的复用性,为泛型编程打下了坚实的基础!
(478条消息) C++基础——模板讲解_橙予清的zzz~的博客-CSDN博客https://blog.csdn.net/weixin_69283129/article/details/127845086
感兴趣的朋友门可以来看看这篇文章,它会加深你对模板的理解。
而接下来我要讲的是模板的另外几个作用:
一.模板的多参数应用:
非类型模板参数 模板参数分类类型形参与非类型形参。
1.类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
2.非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。
在上面的那篇博客中,我所列举的模板例子中用到的全都是类型形参。
// 定义一个模板类型的静态数组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;};
通过上图代码可知:模板形参列表中出现了非类型形参。该参数可以是变量,但其类型只能是整型,这个整型包括:char、int、size_t等类型!而使用自定义类型、浮点类型的变量是不被允许的!会报编译错误!
例:
运行结果:
错误使用1:使用不标准的模板形参表
错误使用2:使用变量作为实参传递给函数模板
二.模板的特例化:
类模板:
函数模板是对函数进行泛型的使用,让函数能够对多种类型的变量做相应的操作;
而类模板就算对类进行泛型的使用,让类中的成员变量或者函数做相应的复杂操作。
//类模板样例1:
template<class T1,class T2>
class Date {
public:Date() {cout << "模板:Date(T1,T2)" << endl;}
private:T1 _a1;T2 _b1;};
针对模板的特化步骤:
1. 必须要先有一个基础的函数模板或者类模板
2. 关键字template后面接一对空的尖括号<>
3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型
4. 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误。
类模板的全特化:
全特化即是将模板参数列表中所有的参数都确定化。
//类模板的特殊化处理——全部参数特殊化处理
template<>
class Date<double,double>{
public:Date() {cout << "全特化:Date(double, double)" << endl;}
private:double _a1;double _b1;
};//类模板的特殊化处理——全部参数特殊化处理2
template<>
class Date<short,char> {
public:Date() {cout << "全特化:Date(short, char)" << endl;}
private:short _a1;char _b1;
};
如上,全特化的类模板所使用的模板形参列表相比较普通的类模板,类型是全部确定的。全特化的作用就是:在一般的情况下,普通的对象被创建时使用普通类模板即可,做着普通的工作。而在某种特殊情况下,我们可以让对象被创建时使用专门的经过特殊化处理的类模板,做一些特殊的操作。
类模板的半特化:
针对模版参数进一步进行条件限制设计的特化,即部分特化模板参数列表。
//半参数特殊化处理——案例1:
template<class T2>
class Date<double, T2> {
public:Date() {cout << "半特化:Date(double, T2)" << endl;}
private:double _a1;T2 _b1;
};//半参数特殊化处理——案例2:
template<class T1>
class Date<T1, char> {
public:Date() {cout << " 半特化:Date(T1, char)" << endl;}
private:T1 _a1;char _b1;
};
类模板原本是T1,T2两个类型的参数,使用半特化就是将T1具体化成double类型作为模板参数。
int main(){Date<int, int> d1;Date<double, double>d2; Date<short,char>d3; Date<double, int> d4; Date<int, char> d5; return 0;}
接着,我们在main函数中使用类创建几个对象,看编译器会进入哪些类模板中!
运行结果:
代码解析:
通过结果可知:d1的创建是调用了类模板T1,T2的构造函数,d2,d3是调用了全特化的类模板构造函数,d4,d5调用了半特化的类模板构造函数。
将这些比作生活的例子:当时间到了吃中午饭的时候,编译器饿了,在它面前有三种吃法:1.自己拿食材做(炒,炸,烧,爆,煎,煮);2.做省时省力的半成品饭;3.点外卖。而T1,T2类型的类模板好比是从超市买回来的新鲜食材,需要编译器自己去做才能吃;半特化的类模板好比是半成品,例如:方便面、自热饭、昨晚的剩饭剩菜,需要编译器进行小小的加工就可以吃了;而全特化的类模板好比是外卖,是现成的热乎的香喷喷的饭菜。在不考虑金钱和健不健康的情况下,我们的做法肯定是选择好吃美味而且省时省力的外卖,编译器的思想也和我们一样——有现成的就不会自己动手再去做。
所以编译器在对d1对象的调用时,发现没有完美符合<int,int>的类模板,那么只能去自己做(使用T1,T2模板的构造函数);
而对于d2对象的调用,发现double,double的构造函数选项有两种,一种是选择<T1,T2>的类,另一种是选择<double,double>的类,那编译器肯定是选择后者。
......
半特化的扩展:
半特化还可以应用于指针、引用的类型上!
template<class T1,class T2>
class Date<T1*,T2*> {
public:Date() {cout << "半特化:Date(T1*,T2*)" << endl;}
private:T1* _a1;T2* _b1;
};//半特化4——两个参数偏特化为引用类型
template<class T1, class T2>
class Date<T1&, T2&> {
public:Date(const T1& d1, const T2& d2): _d1(d1), _d2(d2){cout << "半特化:Data<T1&, T2&>" << endl;}private:const T1 & _d1;const T2 & _d2;
};
三. 模板总结
优点:
1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生
2. 增强了代码的灵活性
相关文章:

C++——模板的作用2:特例化
目录 模板的形式: 一.模板的多参数应用: 例: 错误使用1:使用不标准的模板形参表 编辑 错误使用2:使用变量作为实参传递给函数模板 二.模板的特例化: 类模板: 针对模板的特化步骤&am…...

Python Web开发技巧VII
目录 装饰器inject_serializer 装饰器atomic rebase git 清理add的数据 查看git的当前工作目录 makemigrations文件名称 action(detailTrue, methods["GET"]) 如何只取序列化器的一个字段进行返回 Response和JsonResponse有什么区别 序列化器填表和单字段如…...

LaTex4【下载模板、引入文献】
下载latex模板:(模板官网一般都有,去找) 我这随便找了一个: 下载得到一个压缩包,然后用overleaf打开👇: (然后改里面的内容就好啦) 另外,有很多在线的数学公式编辑器&am…...

【VSCode部署模型】导出TensorFlow2.X训练好的模型信息
参考tensorflow2.0 C加载python训练保存的pb模型 经过模型训练及保存,我们得到“OptimalModelDataSet2”文件夹,模型的保存方法(.h5或.pb文件),参考【Visual Studio Code】c/c部署tensorflow训练的模型 其中“OptimalModelDataSet2”文件夹保…...

windows环境下,安装elasticsearch
目录 前言准备安装 jdk 安装nodejsElasticSearch下载ElasticSearch-head 下载 安装ElasticSearch安装ElasticSearch-head插件设置用户名密码访问ElasticSearch 默认用户名和密码参考 前言 win10elasticsearch 8.9.0 准备 安装 jdk ElasticSearch 是基于lucence开发的&#…...
Elasticsearch入门笔记(一)
环境搭建 Elasticsearch是搜索引擎,是常见的搜索工具之一。 Kibana 是一个开源的分析和可视化平台,旨在与 Elasticsearch 合作。Kibana 提供搜索、查看和与存储在 Elasticsearch 索引中的数据进行交互的功能。开发者或运维人员可以轻松地执行高级数据分析…...

记一次安装nvm切换node.js版本实例详解
最后效果如下: 背景:由于我以前安装过node.js,后续想安装nvm将node.js管理起来。 问题:nvm-use命令行运行成功,但是nvm-list显示并没有成功。 原因:因为安装过node.js,所以原先的node.js不收n…...

生态共建丨YashanDB与构力科技完成兼容互认证
近日,深圳计算科学研究院崖山数据库系统YashanDB V22.2与北京构力科技有限公司BIMBase云平台完成兼容性互认证。经严格测试,双方产品完全兼容、运行稳定。 崖山数据库系统YashanDB是深算院自主研发设计的新型数据库系统,融入原创理论…...
React从入门到实战-react脚手架,消息订阅与发布
创建项目并启动 全局安装 npm install -g create-react-app切换到想创建项目的目录,使用命令:create-react-app 项目名称 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存中…(iQ6hEUgAABpQAAAD1CAYAAABeIRZoAAAAAXNSR0IArs4c6QAAIABJREFUe…...

从零构建深度学习推理框架-1 简介和Tensor
源代码作者:https://github.com/zjhellofss 本文仅作为个人学习心得领悟 ,将原作品提炼,更加适合新手 什么是推理框架? 深度学习推理框架用于对已训练完成的神经网络进行预测,也就是说,能够将深度训练框…...

使用WGCLOUD监测安卓(Android)设备的运行状态
WGCLOUD是一款开源运维监控软件,除了能监控各种服务器、主机、进程应用、端口、接口、docker容器、日志、数据等资源 WGCLOUD还可以监测安卓设备,比如安卓手机、安卓设备等 我们只要下载对应的安卓客户端,部署运行即可,如下是下…...

C++笔记之迭代器失效问题处理
C笔记之迭代器失效问题处理 code review! 参考博文:CSTL迭代器失效的几种情况总结 文章目录 C笔记之迭代器失效问题处理一.使用返回新迭代器的插入和删除操作二.对std::vector 来说,擦除(erase)元素会导致迭代器失效 一.使用返回…...
Tomcat的startup.bat文件出现闪退问题
对于双击Tomcat的startup.bat文件出现闪退问题,您提供的分析是正确的。主要原因是Tomcat需要Java Development Kit (JDK)的支持,而如果没有正确配置JAVA_HOME环境变量,Tomcat将无法找到JDK并启动,从而导致闪退。 以下是解决该问题…...
JAVA8-lambda表达式8:在设计模式-模板方法中的应用
传送门 JAVA8-lambda表达式1:什么是lambda表达式 JAVA8-lambda表达式2:常用的集合类api JAVA8-lambda表达式3:并行流,提升效率的利器? JAVA8-lambda表达式4:Optional用法 java8-lambda表达式5…...
React之组件间通信
React之组件间通信 组件通信: 简单讲就是组件之间的传值,包括state、函数等 1、父子组件通信 父组件给子组件传值 核心:1、自定义属性;2、props 父组件中: 自定义属性传值 import Header from /components/Headerconst Home ()…...

【MATLAB第58期】基于MATLAB的PCA-Kmeans、PCA-LVQ与BP神经网络分类预测模型对比
【MATLAB第58期】基于MATLAB的PCA-Kmeans、PCA-LVQ与BP神经网络分类预测模型对比 一、数据介绍 基于UCI葡萄酒数据集进行葡萄酒分类及产地预测 共包含178组样本数据,来源于三个葡萄酒产地,每组数据包含产地标签及13种化学元素含量,即已知类…...
CF1833 A-E
A题 题目链接:https://codeforces.com/problemset/problem/1833/A 基本思路:for循环遍历字符串s,依次截取字符串s的子串str,并保存到集合中,最后输出集合内元素的数目即可 AC代码: #include <iostrea…...

【深度学习】【Image Inpainting】Generative Image Inpainting with Contextual Attention
Generative Image Inpainting with Contextual Attention DeepFillv1 (CVPR’2018) 论文:https://arxiv.org/abs/1801.07892 论文代码:https://github.com/JiahuiYu/generative_inpainting 论文摘录 文章目录 效果一览摘要介绍论文贡献相关工作Image…...

二维深度卷积网络模型下的轴承故障诊断
1.数据集 使用凯斯西储大学轴承数据集,一共有4种负载下采集的数据,每种负载下有10种 故障状态:三种不同尺寸下的内圈故障、三种不同尺寸下的外圈故障、三种不同尺寸下的滚动体故障和一种正常状态 2.模型(二维CNN) 使…...

redis突然变慢问题定位
CPU 相关:使用复杂度过高命令、O(N)的这个N,数据的持久化,都与耗费过多的 CPU 资源有关 内存相关:bigkey 内存的申请和释放、数据过期、数据淘汰、碎片整理、内存大页、内存写时复制都与内存息息相关 磁盘…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...

ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...