C++模版进阶

一、非类型模版参数

之前学习的模版,参数一般是某种类型,但其实非类型的参数也可以定义在模版里面,但也有一定的限制,只可以定义整形家族的参数,而且具有常量性

注意:

1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。

2. 非类型的模板参数必须在编译期就能确认结果。

namespace chk
{// 定义一个模板类型的静态数组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;};
}

二、模板的特化

1.概念

模板的特化是针对一些较为特殊的情况,可以针对模板的某一种或者某一类实例化去进行特殊的处理,在某些场景下会特别方便

例如,在使用堆时若是想传指针,实际想比较的是指针所指向的内容时,可以对模版进行特化,在针对传模板参数为两个指针时进行特殊处理

// 函数模板 -- 参数匹配
template<class T>
bool Less(T left, T right)
{return left < right;
}
// 对Less函数模板进行特化
template<>
bool Less<Date*>(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;
}

2.特化

特化分为全特化和偏特化,其目的都是为了对模版部分实例化,根据不同的要求进行特殊的处理

特化的格式是:

对需要进行特化处理的部分参数,在template列表里不写,不进行特化的照写,到函数名后一一对应,将特化的部分给具体值或者类型,不特化的部分照写模板,例如:

template<class T,class U,char N>
class chk
{//...
}//全特化
template<>
class chk<int,double,5>
{//...
}//偏特化U为int
template<class T,char N>
class chk<T,int,N>
{//...
}

(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;
};

(2)偏特化

在部分情况下会需要针对某一种具体的情况进行处理,可以用全特化,而往往过多的可以是针对某一类情况进行特殊处理,偏特化的范围是比全特化的范围更大的

偏特化也分两种方式,一种是部分特化,一种是将模板参数进一步的限制,举个例子

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

这是用来给下面两种特化做对比举例的类

部分特化

将部分模板参数特化成具体的类型或者常量,例如:

// 将第二个参数特化为int
template <class T1>
class Data<T1, int>
{
public:Data() {cout<<"Data<T1, int>" <<endl;}
private:T1 _d1;int _d2;
};
对参数进一步限制

例如你穿过来的是指针或者是引用,则会走特化的那一块,这种特化的格式要注意,template里的参数不能省略

//两个参数偏特化为指针类型
template <typename T1, typename T2>
class Data <T1*, T2*>
{ 
public:Data() {cout<<"Data<T1*, T2*>" <<endl;}private:T1 _d1;T2 _d2;
};//两个参数偏特化为引用类型
template <typename T1, typename T2>
class Data <T1&, T2&>
{
public:Data(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. 增强了代码的灵活性

【缺陷】

1. 模板会导致代码膨胀问题,也会导致编译时间变长

2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误

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

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

相关文章

Spring Boot 为什么会出现 ?

Spring Boot出现的背景和原因有以下几个方面&#xff1a; 简化Spring应用的开发和部署&#xff1a;Spring Framework 是一个功能强大但相对复杂的框架&#xff0c;它需要进行繁琐的配置和设置。Spring Boot的目标之一是简化Spring应用的开发过程&#xff0c;减少开发的工作量&a…

达芬奇MacOS最新中文版 DaVinci Resolve Studio 18中文注册秘钥

DaVinci Resolve Studio 18是一款专业的视频编辑软件&#xff0c;它具有多种强大的功能。首先&#xff0c;它提供了丰富的视频剪辑工具&#xff0c;如剪切、复制、粘贴、剪辑、缩放和移动等&#xff0c;使用户可以轻松地剪辑和组合视频素材。其次&#xff0c;该软件还支持多个轨…

数据结构:二叉搜索树

目录 1、二叉搜索树概念 2、 二叉搜索树的插入 3、二叉搜索树的查找 4、二叉搜索树的删除 5、二叉搜索树的中序遍历 实现 1、二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树 &#xff0c;或者是具有以下性质的二叉树 : 若它的左子树不为空&#…

Python第三方库 - Flask(python web框架)

1 Flask 1.1 认识Flask Web Application Framework&#xff08; Web 应用程序框架&#xff09;或简单的 Web Framework&#xff08; Web 框架&#xff09;表示一个库和模块的集合&#xff0c;使 Web 应用程序开发人员能够编写应用程序&#xff0c;而不必担心协议&#xff0c;线…

定档11月2日,YashanDB 2023年度发布会即将启航

数据库作为支撑核心业务的关键技术&#xff0c;对数字经济的发展有着重要的支撑作用&#xff0c;随着云计算、AI等技术的迅猛发展和数据量的爆发式增长&#xff0c;推动着数据库技术的加速创新。 为了应对用户日益复杂的数据管理需求&#xff0c;赋能行业国产化建设和数字化转型…

华为OD 题目汇总 Java【A卷+B卷】2023

华为OD统一考试A卷+B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 华为机试有三道题目,整体难度基本就是力扣中等或简单题,前两道分值为100分,第三道分值为200分。总分为400分…

unity 一键替换 UI上所有字体,批量替换字体(包括:Text和Text (TMP))

前言&#xff1a;在开发中会遇到这种情况&#xff0c;开发完了&#xff0c;发现UI字体没有替换&#xff0c;特别是需要发布到WebGL端的同学&#xff0c;突然发现无法显示汉字了。下面一个非常方便的方法完美解决。 1.解压出来的脚本放在Edit文件下&#xff0c;没有的创建一个 2…

Android 中的 本地广播LocalBroadcastManager

Android 中的 本地广播LocalBroadcastManager 文章目录 Android 中的 本地广播LocalBroadcastManager一、LocalBroadcastManager 的基本作用二 、LocalBroadcastManager 的基本使用1、包的导入&#xff08;1&#xff09;Android 源码中bp文件的导入&#xff1a;&#xff08;2&a…

2016年亚太杯APMCM数学建模大赛A题基于光学信息数据的温度及关键元素含量预测求解全过程文档及程序

2016年亚太杯APMCM数学建模大赛 A题 基于光学信息数据的温度及关键元素含量预测 原题再现 光含有能量&#xff0c;在一定条件下可以转化为热。燃烧是一种常见的现象&#xff0c;既能发光又能发热。光和热通常是同时存在的&#xff0c;一般来说&#xff0c;光强度越高&#xf…

2023年香水行业数据分析:国人用香需求升级,高端香水高速增长

在人口结构变迁的背景下&#xff0c;“Z世代”作为当下我国的消费主力&#xff0c;正在将“悦己”消费推动成为新潮流。具备经济基础的“Z世代”倡导“高颜值”、“个性化”、“精致主义”&#xff0c;这和香水、香氛为代表的“嗅觉经济”的特性充分契合&#xff0c;因此&#…

mysql中limit和offset的用法详细介绍

有的时候我们在学习或者工作中会使用到SQL语句&#xff0c;那么介绍一下limit和offset的使用方法。 mysql里分页一般用limit来实现&#xff0c;例如&#xff1a; 1、select* from user limit 3 表示直接取前三条数据 2、select * from user limit 1,3; 表示取1后面的第2,3,…

翻页视图ViewPager

ViewPager控件允许页面在水平方向左右滑动&#xff0c;就像翻书、翻报纸&#xff0c;Android提供了已经分装好的控件。对于ViewPager来说&#xff0c;一个页面就是一个项&#xff08;相当于ListView的一个列表项&#xff09;&#xff0c;许多页面组成ViewPager的页面项。 List…

【计算机网络笔记】网络应用对传输服务的需求

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

LuatOS-SOC接口文档(air780E)--log - 日志库

常量 常量 类型 解释 log.LOG_SILENT number 无日志模式 log.LOG_DEBUG number debug日志模式 log.LOG_INFO number info日志模式 log.LOG_WARN number warning日志模式 log.LOG_ERROR number error日志模式 log.setLevel(level) 设置日志级别 参数 传入值…

实现打包后暴露可修改接口地址文件

### vue-cli3 实现打包后暴露可修改接口地址文件 在前后端分离的开发模式中,有时候我们开发好打包的文件在部署完之后,需要去修改获取接口的地址,这个时候就需要前端修改完之后重新打包再部署了,但是如果我们只是需要修改接口地址时,反复的重新打包就太麻烦了,接下来就分享一种…

Rust笔记【1】

元组和解构语法 let tup : (i32, f64, u8) (666, 2.0, 1);let tup (666, 2.0, 1); let (x, y, z) tup;let x tup.0; let y tup.1; let z tup.2;数组类型 数组定义是方括号&#xff1a;[ ] 元组定义是小圆括号&#xff1a;( ) 结构体定义是大括号&#xff1a;{ }&#xf…

USB学习(2):USB端点和传输协议(数据包、事物)详解

接着上一篇文章USB学习(1)&#xff1a;USB基础之接口类型、协议标准、引脚分布、架构、时序和数据格式&#xff0c;继续介绍一下USB的相关知识。 文章目录 1 USB端点(Endpoints)1.1 基本知识1.2 四种端点 2 传输协议2.1 数据包类型2.1.1 令牌数据包(Token packets)2.1.2 数据数…

【机器学习合集】激活函数合集 ->(个人学习记录笔记)

文章目录 综述1. S激活函数(sigmoid&Tanh)2. ReLU激活函数3. ReLU激活函数的改进4. 近似ReLU激活函数5. Maxout激活函数6. 自动搜索的激活函数Swish 综述 这些都是神经网络中常用的激活函数&#xff0c;它们在非线性变换方面有不同的特点。以下是这些激活函数的主要区别&am…

学习笔记二十三:Deployment入门到企业实战应用

Deployment入门到企业实战应用 Deployment控制器&#xff1a;概念、原理解读Deployment概述Deployment工作原理&#xff1a;如何管理rs和Pod&#xff1f;什么叫做更新节奏和更新逻辑呢 Deployment使用案例&#xff1a;创建一个web站点,2个副本deploy-demo详细解读 通过k8s实现滚…

分布式:一文搞定Redis/Zookeeper/MySQL实现分布式锁

目录 一、项目准备spring项目数据库 二、传统锁演示超卖现象使用JVM锁解决超卖解决方案JVM失效场景 使用一个SQL解决超卖使用mysql悲观锁解决超卖使用mysql乐观锁解决超卖四种锁比较Redis乐观锁集成Redis超卖现象redis乐观锁解决超卖 三、分布式锁概述四、Redis分布式锁实现方案…