【C++】详细介绍模版进阶,细节满满

目录

一、非类型模版参数:

1、介绍:

2、使用:

3、注意:

4、应用

二、模版特化

(一)、概念

(二)、函数模版特化

1、步骤:

2、举例:

3、不建议使用函数模版特化

(三)、类模版特化

1.全特化:

2、偏特化

2.1、部分特化

2.2、参数更进一步的限制

2.3、注意:

2.4、普通指针变量传递给const指针变量的引用(权限缩小)

三、模版的分离编译

1、什么是分离编译?

2、模版的分离编译

四、模版的优缺点

1.优点:

2、缺点:


一、非类型模版参数:

1、介绍:

模板参数分类类型形参与非类型形参。
类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
非类型形参:就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。

2、使用:

#define N 20
template<class T>
struct stack
{private:T _arr[N];T _top;
};int main()
{stack<int> s1;stack<int> s2;return 0;
}

如上述代码,模拟实现一个数组栈时,栈s1想要10个空间,栈s2想要20个空间,此时的结构就无法实现。

此时我们就可以使用非类型模版参数,即增加一个非类型模版参数:

template<class T,size_t N>
struct stack
{private:T _arr[N];T _top;
};int main()
{stack<int,10> s1;stack<int,20> s2;return 0;
}

此时,我们需要多少变量,就传多少值。

3、注意:

(1)、非类型模版参数只能传整形常量,浮点数、类对象以及字符串等等是不允许作为非类型模板参数的。
(2)、非类型的模板参数必须在编译期就能确认结果。
(3)、模版是按需实例化,只实例化调用过的函数,这就导致即使某些模版函数里面有一些错误,但如果没有调用该函数的话,也不会检查出来。
如上,N为常量,即使fun函数里面对N进行++,但没有对象调用fun函数,编译器就不会报错。

4、应用

应用一:位图

应用二:array容器

二、模版特化

(一)、概念

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理。
例如用仿函数进行大小比较时,如果传入的是指针,我们预期是想比较指针所指向内容的大小,但它会直接比较指针(地址)的大小,这是就需要对这一类型进行特化。

(二)、函数模版特化

1、步骤:

1、必须要先有一个基础的函数模板(正常模版)
2、关键字template后面接一对空的尖括号<>
3、函数名后跟一对尖括号,尖括号中指定需要特化的类型
4、函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误

2、举例:

template<class T>
class test
{
public:test(T a1):a(a1){}bool operator<(test a2){return this->a < a2.a;}
private:int a;
};
//函数特化
template<class T>
bool myLess(T s1, T s2)
{cout << "程序走了正常函数模版" << endl;return s1 < s2;
}template<>
bool myLess<test<int>*>(test<int>* s1, test<int>* s2)
{cout << "程序走了特化" << endl;return *s1 < *s2;
}int main()
{test<int> a1(10);test<int> a2(20);//正常情况cout << "正常情况:" << myLess(10, 20) << endl;//特殊情况test<int>* pa1 = &a1;test<int>* pa2 = &a2;cout << "特殊情况:" << myLess(pa1, pa2);return 0;
}

如上,当我们实现一个函数的功能是比较大小时,如果此时我们实参传的是值的指针,那么函数就会读指针(即地址)进行比较,这样的结果是不确定的,因为申请的空间不确定谁大谁小,同时也不符合我们的预期。此时我们就需要对该指针类型进行特化,如上的test<int>*,根据特化步骤单独写一个特化模版函数,当传入的参数是test<int>*类型时,程序就会调用特化后的函数。

(通俗来讲就是,对某一个类型单独进行处理,当传入的实参类型与特化类型匹配的话就会进入特化后的模版函数)。

3、不建议使用函数模版特化

不建议使用函数模版特化,因为当遇见参数列表有引用或const修饰时的情况,处理起来会变得很麻烦。

上述情况用编译器优先匹配的原则也可以解决,有现成用现成。

bool myLess(test<int>* s1, test<int>* s2)
{cout << "编译器优先匹配" << endl;return s1 < s2;
}

(三)、类模版特化

1.全特化:

全特化即是将模板参数列表中所有的参数都确定化。
//类模板特化
//正常模版
template<class T1,class T2>
class myTest
{
private:T1 _a1;T2 _a2;
public:void fun(){cout << "调用正常模版" << endl;}
};//全特化指针类型
template<>
class myTest<int*,int*>
{
private:int* _a1;int* _a2;
public:void fun(){cout << "调用全特化int指针模版" << endl;}
};int main()
{//正常模版myTest<int,int> aa;aa.fun();//全特化int指针myTest<int*, int*> bb;bb.fun();return 0;
}

注意全特化模版的写法,template<>里面没有数据,将所有模版替换为具体类型(int*为例),这样当,类实例化时传递的参数与之匹配时,就会使用全特化模版。

2、偏特化

2.1、部分特化
将模板参数类表中的一部分参数特化
//偏特化
//正常模版
template<class T1,class T2>
class myTest
{
private:T1 _a1;T2 _a2;
public:void fun(){cout << "调用正常模版" << endl;}
};//部分参数特化
template<class T1>
class myTest<T1,int*>
{
private:T1 _a1;int* _a2;
public:void fun(){cout << "调用部分参数模版" << endl;}
};
int main()
{myTest<char, int*> s1;s1.fun();return 0;
}

类似的,这里我们特化了第二个参数为具体的int*,那么当传模版参数中只要第二个模版参数的类型是int型,那么就会实例化部分参数特化的类。要注意写法。

2.2、参数更进一步的限制
偏特化并不仅仅是指特化部分参数,还可以是针对模板参数更进一步的 条件限制 所设计出来的一个特化版本。如限制类型是指针或者引用等。
//偏特化
//正常模版
template<class T1,class T2>
class myTest
{
private:T1 _a1;T2 _a2;
public:void fun(){cout << "调用正常模版" << endl;}
};部分参数特化
//template<class T1>
//class myTest<T1,int*>
//{
//private:
//	T1 _a1;
//	int* _a2;
//public:
//	void fun()
//	{
//		cout << "调用部分参数模版" << endl;
//	}
//};//进一步限制类型
template<class T1,class T2>
class myTest<T1*, T2*>
{
private:T1* _a1;T2* _a2;
public:void fun(){cout << "调用进一步限制成指针的模版" << endl;}
};int main()
{myTest<char, int> s1;s1.fun();myTest<char*, int*> s2;s2.fun();myTest<double*, char*> s3;s3.fun();return 0;
}
上述写法将模版参数全部限制成指针,不管什么类型的指针,只要两个模版参数都是原生指针,那么就会实例化进一步限制的特化模版类。
2.3、注意:

(1)、全特化和进一步限制特化的区别,通俗来讲可以理解为,全特化只针对一种类型进行特化,而后者则是针对某一类类型,如指针类,引用类.

(2)、同时存在全特化和偏特化,则会优先匹配全特化,后匹配偏特化,因为全特化的类型更加明确,类似于编译器优先匹配原则。如果都匹配不上的就会匹配正常模版。

2.4、普通指针变量传递给const指针变量的引用(权限缩小)

我们知道,普通指针变量是可以传递给const修饰的指针变量的,这样所指向的值是不能改变的,这属于权限缩小问题。同时普通变量也可以传递给引用。

那么当把普通指针变量传递给const指针变量的引用该怎么书写呐?

错误写法:

因为当把int* 传递给const int* 的引用时,中间会产生一个临时变量而临时变量具有常属性,所以我们应该使用const指针变量的const引用进行接收:

正确写法:

三、模版的分离编译

1、什么是分离编译?

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链 接起来形成单一的可执行文件的过程称为分离编译模式。
例如将函数的声明放进 .h 文件,函数的定义放 .cpp 文件,程序翻译的前三个过程.h 和 .cpp是分别进行,最后链接阶段在链接起来。

2、模版的分离编译

函数模版和类模版都不支持声明和定义分离,所以最好的办法就是将声明和定义放在同一个源文件。

四、模版的优缺点

1.优点:

1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生
2. 增强了代码的灵活性

2、缺点:

1. 模板会导致代码膨胀问题,也会导致编译时间变长
2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误

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

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

相关文章

动态规划---解决多段图问题

ok 小伙伴们&#xff0c;我现在有点小小的红温&#xff0c;有点毛躁。 怎么解决多段图问题呢&#xff1f;求取最短路径有多种方法可取。 家人们&#xff0c;毫无思绪可言……………………………… 要实现动态规划&#xff0c;条件&#xff1a;子问题重叠度较高&#xff0c;并…

JMeter基础篇

目录 总目录&#xff1a; 一、JMeter简介&#xff1a; -用途&#xff1a; -优缺点&#xff1a; 二、JMeter安装&#xff1a; 三、项目简介&#xff1a; -学生管理系统&#xff1a; -API接口清单&#xff1a; 查询&#xff1a; 新增&#xff1a; 更新&#xff1a; 删…

Elasticsearch中什么是倒排索引?

倒排索引&#xff08;Inverted Index&#xff09;是一种索引数据结构&#xff0c;它在信息检索系统中被广泛使用&#xff0c;特别是在全文搜索引擎中。倒排索引允许系统快速检索包含给定单词的文档列表。它是文档内容&#xff08;如文本&#xff09;与其存储位置之间的映射&…

【Python特征工程系列】利用SHAP进行特征重要性分析-XGB模型为例(案例+源码)

这是我的第374篇原创文章。 一、引言 SHAP有多种实现方式&#xff0c;每种方式都适用于特定的模型类型&#xff0c;可以实现更快的逼近。 TreeExplainer :TreeExplainer专为树集合方法开发&#xff0c;如XGBoost&#xff0c;LightGBM或CatBoost。 DeepExplainer :DeepExplain…

C++数据结构算法学习

C ,orient(面向) object , object entity(实体) Visible(可见的) or invisible(不可见) 变量用来保存数据 objects attribute(属性) services(服务) C STL 容器 vector, list&#xff08;&#xff09; vector底层是数组&#xff0c;类似双向链表和list底层 map/s…

ELK-Logstash配置

文章目录 一、什么是Logstash、有什么用&#xff1f;什么是 Logstash&#xff1f;Logstash 的主要特点&#xff1a;Logstash 的用途&#xff1a; 二、Logstash的安装与基本配置事先要安装Java的环境&#xff1f;Logstash 安装Debian/UbuntuRed Hat/CentOSmacOS&#xff08;使用…

R语言机器学习与临床预测模型69--机器学习模型解释利器:SHAP

R小盐准备介绍R语言机器学习与预测模型的学习笔记&#xff0c; 快来收藏关注【科研私家菜】 01 机器学习的可解释性 对于集成学习方法&#xff0c;效果虽好&#xff0c;但一直无法解决可解释性的问题。我们知道一个xgboost或lightgbm模型&#xff0c;是由N棵树组成&#xff0c;…

Vue自定义指令详解——以若依框架中封装指令为例分析

自定义指令 在Vue.js中&#xff0c;自定义指令提供了一种非常灵活的方式来扩展Vue的功能。以下是对Vue中自定义指令的详细解释&#xff1a; 一、自定义指令的基本概念 自定义指令允许开发者直接对DOM元素进行低层次操作&#xff0c;而无需编写大量的模板或者JavaScript代码。…

sql server启用远程连接与修改默认端口

一&#xff0c;数据库右键属性 二&#xff0c;sa账号状态属性启用 三&#xff0c;SQL Server配置管理器, 点击SQL Server 服务选项&#xff0c;确定SQL Server是正在运行的。 四&#xff0c;手动修改数据库的连接端口 1&#xff09;确保启用 2)修改默认端口 3)客户端IP改为一…

吴恩达机器学习笔记(3)

吴恩达机器学习&#xff08;3&#xff09; tensorflow实现 用 TensorFlow 实现神经网络 以下是一个完整的代码示例&#xff0c;展示如何使用 TensorFlow 和 Keras 构建和训练一个简单的神经网络来处理 MNIST 数据集&#xff1a; import tensorflow as tf from tensorflow.k…

【入门篇】A+B Problem——多语言版

AB Problem 跳转 题目分析&#xff1a; 这个题目要求输入两个整数 a 和 b&#xff0c;然后输出它们的和。需要注意的是 a 和 b 的绝对值都不超过 10^9。此外&#xff0c;题目中提到了 Pascal 使用 integer 类型可能会爆掉&#xff0c;说明需要使用更大范围的数据类型来处理这…

Matlab实现鹈鹕优化算法(POA)求解路径规划问题

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1内容介绍 鹈鹕优化算法&#xff08;POA&#xff09;是一种受自然界鹈鹕捕食行为启发的优化算法。该算法通过模拟鹈鹕群体在寻找食物时的协作行为&#xff0c;如群飞、潜水和捕鱼等&#xff0c;来探索问题的最优解。POA因其…

LED和QLED的区别

文章目录 1. 基础背光技术2. 量子点技术的引入3. 色彩表现4. 亮度和对比度5. 能效6. 寿命7. 价格总结 LED和 QLED都是基于液晶显示&#xff08;LCD&#xff09;技术的电视类型&#xff0c;但它们在显示技术、色彩表现和亮度方面有一些关键区别。以下是两者的详细区别&#xff…

《JavaEE进阶》----20.<基于Spring图书管理系统①(登录+添加图书)>

PS&#xff1a;关于接口定义 接口定义&#xff0c;通常由服务器提供方来定义。 1.路径&#xff1a;自己定义 2.参数&#xff1a;根据需求考虑&#xff0c;我们这个接口功能完成需要哪些信息。 3.返回结果&#xff1a;考虑我们能为对方提供什么。站在对方角度考虑。 我们使用到的…

OpenEuler 下 Docker 安装、配置与测试实例

文章目录 前言1. 环境准备2. 下载 Docker3.配置服务文件4.配置加速器加速下载docker镜像5. 验证 Docker 安装 前言 Docker 安装大致分为包管理器安装、脚本安装、离线手动安装、容器编排工具安装、桌面版安装等&#xff0c;每种安装各有特点&#xff0c;但涉及知识面不少&…

如何线程安全的使用HashMap

前言 Map一直是面试中经常被问到的问题。博主在找工作的过程中&#xff0c;就被问到了这样一个问题&#xff1a; Map是线程安全的吗&#xff1f;我不考虑使用线程安全的Map(eg&#xff1a;ConcurrentHashMap) 。如何在多线程/高并发下安全使用 HashMap&#xff1f; 当时博主…

Android CarrierConfig 参数项和正则匹配逻辑

背景 在编写CarrierConfig的时候经常出现配置不生效的情况&#xff0c;比如运营商支持大范围的imsi&#xff0c;或者是测试人员写卡位数的问题等等&#xff0c;因此就需要模式匹配&#xff08;包含但不限于正则表达式&#xff09;。 基本概念: 模式匹配涉及定义一个“模式”&a…

现代Web开发:Vue 3 组件化开发实战

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 现代Web开发&#xff1a;Vue 3 组件化开发实战 现代Web开发&#xff1a;Vue 3 组件化开发实战 现代Web开发&#xff1a;Vue 3 组…

吾店云介绍 – 中国人的WordPress独立站和商城系统平台

经过多年在WordPress建站领域的摸索和探索&#xff0c;能轻松创建和管理各种类型网站的平台 – 吾店云建站平台诞生了。 应该说这是一个艰苦卓绝的过程&#xff0c;在中国创建一个能轻松创建和使用WordPress网站的平台并不容易&#xff0c;最主要是网络环境和托管软件的限制。…

「QT」几何数据类 之 QLine 整型直线类

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「QT」QT5程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid…