模板进阶和反向迭代器

文章目录

  • 模板
    • 非类型模板参数
    • 模板特化
      • 函数模板特化
      • 类模板特化
    • 模板分离编译
  • 反向迭代器

模板

非类型模板参数

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

在这里插入图片描述
注意:

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

模板特化

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理。比如两个数比较的话,如果参数是指针的话,就不能正常的用大于小于会比较,应该先解引用在比较,否则就会导致结果与我们预期的相反。
模板特化中分为函数模板特化与类模板特化。

函数模板特化

在这里插入图片描述
此时,就需要对模板进行特化。即:在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。
在这里插入图片描述
一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给出。

在这里插入图片描述

该种实现简单明了,代码的可读性高,容易书写,因为对于一些参数类型复杂的函数模板,特化时特别给出(可以构成函数重载),因此函数模板不建议特化,建议直接使用函数重载。

类模板特化

  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;
};
  1. 偏特化

任何针对模版参数进一步进行条件限制设计的特化版本。

部分特化

将模板参数类表中的一部分参数特化。

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

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

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

模板分离编译

什么是分离编译呢?

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

我们在写模版分离编译的时候会发现出现链接错误,这是因为我们在主函数中使用了模版函数,我们有这个函数的声明,所以在编译期间不会报错,但是在实现模版函数的那个.cpp文件中并不知道我们要的是什么类型,并没有给我们实例化出相应的代码,所以会出现找不到外部符号。

在这里插入图片描述
解决这个问题有两种方法:

  1. 显示实例化
    但是这种方法很局限,并不适合长久之计。
  2. 将声明和定义放到一个文件"xxx.hpp"里面或者xxx.h其实也是可以的。
    我们一般都使用方法二。

总结

优点:

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

缺点:

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

反向迭代器

反向迭代器我们可以直接将整型迭代器复制一个,然后改一下操作,就可以实现出来我们正常人能够想到的一个反向迭代器版本。我们今天来学习学习大佬的思路,我们会发现正向迭代器和反向迭代器他们的大部分功能都是语一样的,那我们可不可以用一个正向迭代器,用我们的适配器适配出来一个反向迭代器呢?

这个反向迭代器,不仅仅使用于我们的一个容器,而是适用于我们的所有容器。

在这里插入图片描述
在这里插入图片描述

我们通过图,不难发现我们在访问之前先访问end()的前一个元素然后等到迭代器停止时,就可以拿到容器中所有元素。只不过,我们的反向迭代器是反着来的,对于++就是正向迭代器的–,所以我们就可以通过这样的一个想法,来通过一个正向迭代器适配出一个反向迭代器,但是还有一个问题就是,我们并不知道容器中元素的类型,其实这个也好说,我们在实例化模板是直接传过来就可以了。类似于正向迭代器的const于非const版本一样。这样我们不仅能实现一个非const的反向迭代器,连const版本的也实现好了。

template <class Iteraior,class Ref,class Ptr>
class Reverse_iterator
{
public:typedef Reverse_iterator<Iteraior, Ref, Ptr> self;Reverse_iterator(const Iteraior& it):_it(it){}self& operator++(){--_it;return *this;}self operator++(int){self tmp = *this;--_it;return tmp;}bool operator!=(const self& s){return _it != s._it;}bool operator==(const self& s){return _it == s._it;}Ref operator*(){Iteraior tmp = _it;return *(--tmp);}Ptr operator->(){return &(*_it);}
private:Iteraior _it;
};

那么今天的分享就到这里了,有什么不懂得可以私信博主,或者添加博主的微信,欢迎交流。

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

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

相关文章

基于CodeFormer实现图片模糊变清晰,去除马赛克等效果

前言 CodeFormer是一种基于AI技术深度学习的人脸复原模型&#xff0c;由南洋理工大学和商汤科技联合研究中心联合开发。该模型通过结合了VQGAN和Transformer等技术&#xff0c;可以通过提供模糊或马赛克图像来生成清晰的原始图像。可以实现老照片修复、照片马赛克修复、黑白照…

【ARM Coresight 系列文章 9.1 -- ITM 仪器化跟踪宏单元详细介绍】

文章目录 1.1 ITM 介绍1.1.1 ITM 功能介绍1.1.2 Cortex-M ITM 的地址范围1.2 ITM 使用1.2.1 ITM 寄存器介绍1.2.2 Cortex-M7 ITM 代码示例1.2.3 Cortex-M33 ITM 代码示例1.1 ITM 介绍 在debug 调试阶段通常都是使用 printf(printk) 来进行进行 log 输出,然后定位问题。那么如…

排序算法-希尔排序法(ShellSort)

排序算法-希尔排序法&#xff08;ShellSort&#xff09; 1、说明 我们知道当原始记录的键值大部分已排好序的情况下插入排序法非常有效&#xff0c;因为它不需要执行太多的数据搬移操作。希尔排序法是D.L.Shell在1959年7月发明的一种排序法&#xff0c;可以减少插入排序法中数…

Java IO流

IO 即 Input / Output &#xff0c;输入输出流。IO流在Java中分为输入流和输出流&#xff0c;而根据数据的处理方式又分为字节流和字符流。 Java IO 流的 40 多个类都是从如下 4 个 抽象类基类中派生出来的。 InputStream /Reader : 所有的输入流的基类&#xff0c;前者是字节…

论文阅读之《Learn to see in the dark》

Learning to See in the Dark-CVPR2018 Chen ChenUIUC&#xff08;伊利诺伊大学厄巴纳-香槟分校&#xff09; Qifeng Chen, Jia Xu, Vladlen Koltun Intel Labs(英特尔研究院) 文章链接&#xff1a;https://arxiv.org/pdf/1805.01934.pdfhttps://arxiv.org/pdf/1805.01934.p…

Android Studio展示Activty生命周期

前言 本文章以及之后文章的程序版本使用Android Studio 2022.3.1 Patch 1 版本编辑&#xff0c;使用语言为java&#xff0c;最低支持API 27 Android 8.1&#xff0c;构建工具版本如下&#xff1a; 本文章主要是介绍Activty跳转和删除&#xff0c;以备后续使用&#xff0c;所以就…

计算机的字符与编码集

文章目录 前言一、字符编码集的历史1.ASCII码2.Extended ASCII码3.字符编码集的国际化 二、中文编码集 前言 今天给大家介绍计算机的字符与编码集&#xff0c;分为两部分&#xff1a;字符编码集的历史、中文编码集。 一、字符编码集的历史 这部分包含三个板块内容&#xff1a…

【通信系列 5 -- HTTPS 介绍】

文章目录 1.1 HTTPS链接网址1.1.1 HTTPS 产生背景1.1.2 HTTPS工作内容1.1.3 SSL/TLS1.1.4 TLS 的命名规范1.1.5 TLS 加密算法1.1.6 分组模式1.1.7 摘要算法1.1.8 非对称加密1.1.9 CA认证 1.2 openssl1.2.1 RSA 签名验签 1.1 HTTPS链接网址 HTTP 是一种 超文本传输协议(Hyperte…

DOCKER本地仓库

概述 随着docker的应用越来越多&#xff0c;安装部署越来越方便&#xff0c;批量自动化的镜像生成和发布都需要docker仓库的本地化应用。 试用了docker的本地仓库功能&#xff0c;简单易上手&#xff0c;记录下来以备后用。 环境 centos&#xff1a;CentOS release 7.0 (F…

CANoe创建仿真工程

CANoe创建仿真工程 写在前面仿真工程的创建创建工程添加CAN数据库添加系统变量创建面板创建网络节点为节点添加代码工程运行测试总结 写在前面 Canoe的安装不是特别方便&#xff0c;我是参加了松勤的培训课程&#xff0c;不仅需要安装软件还需要安装驱动&#xff0c;刚刚学习的…

【PWN · 栈迁移】[CISCN 2019东南]PWN2

一道非常典型、适合用作学习栈迁移的题目。 前言 当存在栈溢出但是溢出字符数并不多的情况下&#xff0c;可以尝试在别处构造rop链&#xff0c;通过栈迁移到目标内存区域&#xff0c;执行rop链。这里不讲栈迁移原理&#xff0c;仅是对题目的分析&#xff0c;适合对栈迁移有初步…

WPF中的多重绑定

MultiBinding 将会给后端传回一个数组, 其顺序为绑定的顺序. 例如: <DataGridMargin"10"AutoGenerateColumns"False"ItemsSource"{Binding Stu}"><DataGrid.Columns><DataGridTextColumn Binding"{Binding Id}" Header…

bash一行输入,多行回显demo脚本

效果图&#xff1a; 脚本&#xff1a; #!/bin/bash # 定义一个变量&#xff0c;用来存储输入的内容 input"" # 定义一个变量&#xff0c;用来存储输入的字符 char""# 为了让read能读到空格键 IFS_store$IFS IFS# 提示内容&#xff0c;在while循环中也有&a…

three.js入门 —— 实现第一个3D案例

前言&#xff1a; three.js入门&#xff0c;根据文档实现第一个3D案例 效果图&#xff1a; 代码实现&#xff1a; const scene new THREE.Scene();//创建一个长方体几何对象Geometryconst geometry new THREE.BoxGeometry(100, 100, 100);//创建一个网络基础材质的材质对象…

机器人革命:脑洞大开的前沿机器人技术!

原创 | 文 BFT机器人 01 由生物启发的多模式移动形态机器人 在一个不断运动的世界中&#xff0c;一种新开发的名为M4&#xff08;多模式移动形态机器人&#xff09;的机器人展示了在包括滚动、飞行和行走在内的八种不同运动模式之间切换的能力。这款机器人由加州理工学院自主…

SOLIDWORKS® 2024 新功能 - 3D CAD

1、 先前版本的兼容性 • 利用您订阅的 SOLIDWORKS&#xff0c;可将您的 SOLIDWORKS 设计作品保存为旧版本&#xff0c;与使用旧版本 SOLIDWORKS 的供应商无缝协作。 • 可将零件、装配体和工程图保存为新版本前两年之内的SOLIDWORKS 版本。 优点&#xff1a; 即使其他用户正…

conda 创建虚拟环境

1.为什么要创建虚拟环境 我们在做开发或者跑论文实验可能会同时进行多个任务&#xff0c;这些任务可能会依赖于不同的python环境&#xff0c;比如有的用到3.6有的用到3.7&#xff0c;这时我们创建不同版本的python&#xff0c;放到虚拟环境中给不同的任务分别提供其所需要的版本…

Git相关知识(1)

目录 1.初识Git 1.基础知识 2.centos中下载 2.基本操作 1.创建本地仓库 2.配置本地仓库 3.版本库、工作区、暂存区 4.添加文件 5.add和commit对git文件的作用 6.修改文件 7.版本回退 8.撤销修改 9.删除文件 3.分支操作 1.HEAD与分支 2.创建分支 3.删除分支 …

基于SSM的班级事务管理系统

基于SSM的班级事务管理系统 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台界面 登录界面 班委界面 学生界面 管理员界面 摘要 基于SSM&#xff08;Spring、Spring…

ARM-day9作业

main.c: #include "uart.h"#include "key_it.h"int main(){char c;char *s;uart4_init(); //串口初始化//中断初始化key_it_config();key3_it_config();//完成GPIO相关初始化all_led_init();//风扇初始化fs_init();//蜂鸣器初始化fmq_init();while(1){…