IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C++】模板特化、模板分离编译 -> 正文阅读

[C++知识库]【C++】模板特化、模板分离编译

一、非类型模板参数

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

当我们想定义以一个模板数组,但是不确定其长度时,我们只能以这种方式进行定义:
模板参数

此时便暴露出其问题,关于数组的长度设定,我们没有办法设置其符合泛型编程的特点。

所以我们引入非类型模板参数的写法,就可以解决该问题。如下:
非类型模板参数
两者的区别:
在这里插入图片描述

这样,关于该成员变量数组的长度就可以由用户主动设置长度了。

注意:
1.浮点数、类对象以及字符串是不允许作为非类型模板参数的。
2.非类型的模板参数必须在编译期就能确认结果。

1.1 STL中的 array

以上我们的举例,其实在 STL 中便有其原型 : array的介绍,其实原理就是按照我们上面的非类型模板参数来实现的。
STL中的array
其本质就是一个容器数组。
使用区别:
在这里插入图片描述
可能大家感觉这定义这么相似,两者间没有太大任何区别。

array本质上是一个容器,是使用对象定义的。
而 数组本质就是指针

既然 C++11 带来了 array ,就说明其必然是有优势所在。
优势在于:

array中,不管越界写、越界读都会被检查到。其对越界的检查非常严格
本质上,array 对越界的检查是通过函数的调用来检查,而数组本质上是指针解引用,报错、奔溃与否与编译器有很大关系。编译器检查越界是采用抽查的方式,而且只针对越界写入,越界读不检查。

二、模板的特化

2.1 概念

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理,比如:实现了一个专门用来进行小于比较的函数。
之前我们实现了一个日期类,那现在出现了以下场景:
在这里插入图片描述
大家发现,为什么第三个结果是错误的呢?
因为我们传入的是指针,所以 Greater 函数中是按两个指针的地址来比较的。
这肯定不是我们想要的结果。我们想即使我们传入日期对象的地址,调用该函数,内部使用指针指向的对象进行比较。
所以,这里便引入模板特化的技术。
**特化———针对某些类型进行特殊化处理**

2.2 函数模板特化

函数模板的特化步骤:
1.必须要先有一个基础的函数模板
2.关键字 template 后面接一对空的尖括号 <>
3.函数名后跟一堆尖括号,尖括号中指定需要特化的类型
4.函数形参表:必须要和模板函数的基础参数类型完全相同,如果不同编译器会进行报错。

接下来我们将 Greater 进行特化(注意写法!),然后我们来观察结果。
在这里插入图片描述

注意
一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是讲该函数直接给出。

bool Greater(Date* left,Date* right)
{
	return *left< *right ;
} 

这种实现简单明了,代码可读性高,容易书写,因为对于一些参数类型复杂的函数模板,特化时特别给出,因此函数模板在此种场景下不适合特化。

2.3 类模板特化

我们使用仿函数代替上面的 Greater 函数,同样会出现以下这样情况:
在这里插入图片描述

所以,接下来我们对上面的仿函数进行特化,大家注意特化的格式。

在这里插入图片描述
此时可能会有人觉得特化很鸡肋,这里举一个很常见的使用场景。
比如之前实现的 priority_queue (优先级队列),实现了特化,我们可以直接将指针传入存放到优先级队列中,这样,队列中即是有序数据,而且提高了入队列、调整节点的效率。
在这里插入图片描述

2.3.1 全特化

其实特化分为全特化和偏(半)特化,具体是什么样的,以及其使用场景,我们一起往下学习。

全特化即是将模板参数列表中的所有参数都确定化

全特化定义方式:
在这里插入图片描述

2.3.2 偏特化

任何针对模板参数进一步进行条件限制设计的特化版本。比如对于以下模板。

偏特化有以下两种表现方式:

  • 部分特化

一个参数可以是任意类型,而第二个参数类型必须为 char 型。

在这里插入图片描述

  • 参数更进一步的限制

偏特化并不仅仅是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本。

在这里插入图片描述

接下来是引用偏特化,这个使用就比较奇特了。

在这里插入图片描述

当然,多变的偏特化还可以同时使用引用和指针

在这里插入图片描述
有了以上的基础,所以我们可以对我们上面的特化进行升级,直接使用偏特化,只要是指针,就调用该特化在这里插入图片描述
这样,可以进一步增强代码的通用性。

三、模板分离编译

3.1 什么是分离编译

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译编译。

3.2 模板的分离编译

模板不支持分离编译

一般的 cpp 文件,test.h 中放入声明,test.cpp 放定义。

例如现在,我们将我们自己实现的 vector 容器中的 push_back 和 insert 放到另外一个文件中进行定义。

第一步就会碰到以下错误

在这里插入图片描述

为什么这个地方要加上 typename

在这里插入图片描述

原因:
因为面对这种场景,编译器无法区分用户这样书写,表示的是一个变量还是一个类型,所以需要我们人为去指定该场景下到底是变量还是类型,所以这里我们加上 typename 声明此时是类型。

接着我们运行我们的main()函数。

此时便出现了链接的错误。
而链接的错误提示为有声明push_back的声明,但找不到其定义。
在这里插入图片描述
为什么找不到 push_back 呢?

因为 push_back 没有被实例化.

在这里插入图片描述

总结
1.其余函数在编译期间就已实例化,确定了地址。
2.而push_back在vector.h外,在链接阶段进行匹配
3.push_back 由模板定义,由于模板参数还未实例化,则无法被编译为指令
4.所以push_back未进入符号表,无法被链接

解决方法:

1.模板的声明和定义不分离,或只分离到同一个文件中。
2.显示实例化,直接指定该模板参数的类型,然其进入符号表即可。

在这里插入图片描述
但是这种写法非常的鸡肋,如果此时 模板参数不为 int ,那这里又要添加一次显示实例化。
在这里插入图片描述
再添加一条显示实例化:
在这里插入图片描述
所以,这种方法并不推荐。
这里有一篇关于模板分离式编译更详细的讲解:
为什么C++编译器不能支持对模板的分离式编译

四、模板总结

优点

  • 增强复用了代码,节省资源,更快的迭代开发,将重复的工作交给了编译器
  • C++的标准模板库(STL)因此而生
  • 增强了代码的灵活性

缺陷

  • 模板会导致代码膨胀问题,也会导致编译时间变长
  • 出现模板编译错误时,错误信息非常凌乱,不易定位错误
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 20:56:54  更:2022-10-22 21:00:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 4:03:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码