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. 出现模板编译错误时,错误信息非常凌乱,不易定位错误
相关文章:
C++模版进阶
一、非类型模版参数 之前学习的模版,参数一般是某种类型,但其实非类型的参数也可以定义在模版里面,但也有一定的限制,只可以定义整形家族的参数,而且具有常量性 注意: 1. 浮点数、类对象以及字符串是不允…...

CloudCompare
CloudCompare 源码编译Windows 功能格式转换 源码编译 Windows 源码编译出来的默认基本不带几个插件,包括保存为 .las 的功能 可以直接从 https://www.danielgm.net/cc/ 下载编译好的版本,插件比较多。也有免安装版本 cmake -B build -S . -G "Vi…...

【算法小课堂】深入理解前缀和算法
前缀和是指某序列的前n项和,可以把它理解为数学上的数列的前n项和,而差分可以看成前缀和的逆运算。合理的使用前缀和与差分,可以将某些复杂的问题简单化。 我们通过一个例子来理解前缀和算法的优势: 一维前缀和: ww…...

元对象系统功能
元对象系统功能 建立工程 布局页面 布局页面 修改原件名称 建立元对象 函数作为接口 增加一些固定的属性 #------------------------------------------------- # # Project created by QtCreator 2023-10-24T21:54:44 # #----------------------------…...

【2024秋招】小米中间件后端开发一面2023-9-13-base武汉
1 自我介绍 2 快手实习 2.1 讲讲你写的curd启动器,做了哪些工作呢 答: 2.2 网上也有一些开源的curd代码生成器,你为什么需要自研呢(重要) 答: (1)这个必须得自研,因…...

SpringMVC Day 01:入门案例
前言 在我们的日常工作和学习中,Web 开发是一个无法回避的重要环节。而在 Java Web 开发领域,SpringMVC 无疑是一个重量级选手。它以其灵活性、强大功能和清晰的 MVC 结构,赢得了大量开发者的青睐。但是,对于初学者来说ÿ…...

docker、docker-compose安装教程,很详细
docker、docker-compose安装教程,很详细 一、卸载旧版1、查看有没有安装过旧版2、停止docker3、删除安装过docker的相关包4、删除docker相关的镜像和容器 二、docker安装1、设置阿里云镜像2、查看所有docker3、安装最新版本4、安装指定版本 三、使用前准备1、启动do…...

源代码转换:Tangible Software Solutions 23.10 Crack
Tangible Software Solutions The Most Accurate and Reliable Source Code Converters Convert between C#, Java, C, Python, & VB, while saving countless hours of painstaking work and valuable time.源代码转换 Key Benefits Saves valuable time Accurate and com…...

SAD notes
ESKF 总结 prediction 更新误差先验 F F F通过3.42来算 得到 这里有点绕的一点是: 误差状态的 F F F牵涉到名义状态, 而名义状态又需要在时间上推进更新 其中, F中的名义状态的推进通过公式3.41得到, (名义状态不考虑误差, 这一点从3.41d, 3.41e可以看出, 误差状态只考虑…...

[SQL开发笔记]BETWEEN操作符:选取介于两个值之间的数据范围内的值
一、功能描述: BETWEEN操作符:选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。 二、BETWEEN操作符语法详解: BETWEEN操作符语法: SELECT column1, column2,…FROM table_nameWHERE column BETWEEN val…...

Babylonjs学习笔记(三)——创建天空盒
书接上回,这里讨论创建天空盒!!! // 天空盒const envTex CubeTexture.CreateFromPrefilteredData(./env/environmentSpecular.env,scene)scene.environmentTexture envTex;scene.createDefaultSkybox(envTex,true)scene.environ…...
【计算机网络】文件传输协议FTP和SFTP
1. 介绍 SFTP(SSH文件传输协议)和FTP(文件传输协议)都是用于在计算机之间传输文件的网络协议。FTP和SFTP都位于OSI模型中的应用层。这两种协议用于文件传输和管理,是应用层协议,因此它们工作在OSI模型的最…...
Python 编程语言的介绍
Python 是一种高级、动态类型的解释型语言。由 Guido van Rossum 于1989年底发明,并在1991年首次发布。Python 的设计哲学强调代码的可读性和简洁的语法,特别是使用缩进来表示代码块,这使得开发者能够用更少的代码表达想法。 基础概念: 语法…...

centos服务器搭建安装Gitlab教程使用教程
1、更新服务器: sudo yum update -y && sudo yum upgrade -y 2、下载Gitlab的RPM包 https://packages.gitlab.com/gitlab/gitlab-cece表示开源el表示centos 选64位el8对应CentOS8 本教程以centos8为例,在服务器中,下载centos8的…...

linux复习笔记02(小滴课堂)
linux下输入输出错误重定向: 输入重定向:< 一个大于号是进行了覆盖。 两个大于号是追加。 输出重定向可以用于以后日志打印。 错误重定向: 错误重定向是不把信息打印到屏幕上而是打印到指定文件中去: 输出重定向其实是用的1…...
AWVS漏洞扫描使用基础与介绍
漏洞扫描的基本概念和原理 漏洞扫描是指通过使用自动化工具和技术来检测和识别计算机系统和网络中可能存在的安全漏洞,用于帮助网络安全运维人员及时获取网络安全态势。漏洞扫描是网络安全中的重要环节,它可以帮助我们发现和修复网络中的安全漏洞&#x…...
Flink 维表关联
1、实时查询维表 实时查询维表是指用户在 Flink 算子中直接访问外部数据库,比如用 MySQL 来进行关联,这种方式是同步方式,数据保证是最新的。但是,当我们的流计算数据过大,会对外 部系统带来巨大的访问压力࿰…...
阳光蟹场小程序的盈利模式与思考深度
随着移动互联网的快速发展,小程序成为了各行各业进行数字化转型的重要工具之一。阳光蟹场小程序作为一款专为蟹场管理和销售提供支持的移动,其盈利模式也备受关注。本文将从阳光蟹场小程序的盈利途径、商业模式和对蟹场管理的影响等方面,深入…...
2-Java进阶知识总结-7-UDP-TCP
文章目录 网络编程概述网络编程三要素--IP地址IP地址--概念(IP:Internet Protocol)IP地址--分类IP地址--特殊的地址:127.0.0.1IP地址获取--DOS命令IP地址获取--InetAddress类 网络编程三要素--端口端口--概念端口号 网络编程三要素…...

C++数据结构X篇_19_排序基本概念及冒泡排序(重点是核心代码,冒泡是稳定的排序)
文章目录 1. 排序基本概念2. 冒泡排序2.1 核心代码2.2 冒泡排序代码2.3 查看冒泡排序的时间消耗2.4 冒泡排序改进版减小时间消耗 1. 排序基本概念 现实生活中排序很重要,例如:淘宝按条件搜索的结果展示等。 概念 排序是计算机内经常进行的一种操作,其目…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...