手搓反向迭代器

前言

关于反向迭代器,字如其名,就是将正向迭代器,从反方向再迭代一次就成了,所以我们如此设计反向迭代器:

  1. 假设我们已经拥有了一套能够使用,且包含模板的正向迭代器
  2. 利用适配器模式,让反向迭代器封装正向迭代器
  3. 利用模板的设计,让反向迭代器可以适应多种类型

统一使用规范

对于正向迭代器,为了确保各种容器使用时的统一性(名字统一,操作统一),我们常用typedef 来更改名字、用运算符重载来更改运算规则,达到使用时的统一。而反向迭代器也是如此

例:

正向:typedef __list_iterator<T,T&,T*> iterator;

反向:typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;

这里是自定义实现的list的正向/反向迭代器,由于原生指针不满足所需,所以对原生指针进行了封装,封装成了__list_iterator类,给他取名叫iterator
然后再一步对正向迭代器进行封装,形成了反向迭代器,给他取名叫reverse_iterator
这个有3个模板参数:template<class Iterator,class Ref,class Ptr>,这3个参数会在后文说明

正向:typedef T* iterator;

反向:typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;

这是定义的vector的正向/反向迭代器,由于其在存储空间上是连续的,所以原生指针就可以满足正向迭代器的需求,所以给T*取名叫iterator
然后再一步对正向迭代器进行封装,形成了反向迭代器,取名叫reverse_iterator


迭代器的模板参数

template<class iterator,class Ref,class Ptr>

class iterator

iterator是该反向迭代器封装的正向迭代器的类型,所以理论上该反向迭代器可以适用于任何正向迭代器。

class Ref

对于反向迭代器内部的某些操作,可能需要返回T&,所以除了iterator这一模板参数外,还要添加一个引用类型的模板参数Ref(reference)。

class Ptr

有些操作可能需要返回T*,所以增加了Ptr这一模板参数
例:这里的reverse_iterator传的参就是对应上面的参数

		typedef __list_iterator<T,T&,T*> iterator;typedef __list_iterator<T,const T&,const T*> const_iterator;typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;typedef Reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;

运算符重载的各种实现

反向迭代器的构造函数

由于反向迭代器只需要封装一个元素:iterator,所以他的成员变量只有一个

    Iterator _it;Reverse_iterator(Iterator it):_it(--it){ }

他的构造函数则如上表示,原因如下图

在这里插入图片描述

对于反向迭代器,它采用的是rend()rbegin(),这也是常用的取法
rend():等价于begin()
rbegin():等价于end()
但是由于rbegin()的位置并不是最后一个元素所在的位置,并且非有效位,所以在初始化构造的时候就需要对正向迭代器进行 - - 操作,使得其指向最后一个有效位

operator++ && operator- -

对于这一对运算符,他们要做的正好和符号相反,++要实现的实际上是正向迭代器的- -,所以实现起来也很简单,反向迭代器的++调用正向迭代器的- -,反向迭代器的–调用正向迭代器的++

	self& operator++()//前置++{--_it;return *this;}self operator++(int)//后置++。由于返回值是一个临时变量,所以不能引用返回{self cur = _it;_it--;return cur;}self& operator--(){++_it;return *this;}self operator--(int){self cur = _it;_it++;return cur;}

operator* && operator-> && operator== && operator!=

这些运算符的实现需求都与正向迭代器相同,所以他们只需要调用正向迭代器的对应操作就可以实现

	Ref operator*(){return *_it;}bool operator!=(const self& tmp){return _it != tmp._it;}bool operator==(const self& tmp){return _it == tmp._it;}Ptr operator->(){return _it.operator->();//这里的_it的实现是:return &xxx;有取地址符,返回的是一个指针}

operator[]

该运算符对list无用(没有实现 [ ] 重载的情况下),但是对vector、string…有用

其作用就是返回该容器某个位置的引用

	Ref operator[](size_t pos){return *(_it + pos);}

这里是对存储空间连续的结构,去找到pos位置的元素,并对其解引用,返回该点的引用。

如果非要实现对存储空间不连续的结构,需要重载其 [ ] ,然后上述重载仍然适用

反向迭代器代码

template<class Iterator, class Ref, class Ptr>
struct Reverse_iterator
{typedef Reverse_iterator<Iterator, Ref, Ptr> self;Reverse_iterator(Iterator it):_it(--it){ }Iterator _it;Ref operator[](size_t pos){return *(_it + pos);}self& operator++(){--_it;return *this;}self operator++(int){self cur = _it;_it--;return cur;}self& operator--(){++_it;return *this;}self operator--(int){self cur = _it;_it++;return cur;}Ref operator*(){return *_it;}bool operator!=(const self& tmp){return _it != tmp._it;}bool operator==(const self& tmp){return _it == tmp._it;}Ptr operator->(){return _it.operator->();}
};

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

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

相关文章

软件测试生命周期

本章简要介绍了软件开发项目中常用的生命周期模型&#xff0c;并解释了测试在每个模型中扮演的角色。它讨论了各种测试级别和测试类型之间的区别&#xff0c;并解释了这些在开发过程中的应用位置和方式。 大多数软件开发项目是按照事先选择的软件开发生命周期模型来计划和执行…

ZK监控方法以及核心指标

文章目录 1. 监控指标采集1.1 zk版本高于3.6.0监控指标采集1.2 zk版本低于3.6.0监控指标采集1.3 配置promethues采集和大盘 2. 核心告警指标3. 参考文章 探讨zk的监控数据采集方式以及需要关注的核心指标&#xff0c;便于日常生产进行监控和巡检。 1. 监控指标采集 3.6.0 版本…

ORA-12528: TNS: 监听程序: 所有适用例程都无法建立新连

用了网上的办法&#xff1a; 1、修改listener.ora的参数,把动态的参数设置为静态的参数,红色标注部分 位置D:\oracle\product\10.2.0\db_1\NETWORK\ADMIN SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME PLSExtProc) (ORACLE_HOME D:\oracle\produ…

基于PHP反序列化练习

PHP创建一个以自己姓名命名的类&#xff0c;要求存在两个属性&#xff0c;name&#xff0c;age&#xff0c;进行序列化&#xff0c;输出序列化以后的数据。 <!-- PHP创建一个以自己姓名命名的类&#xff0c;要求存在两个属性&#xff0c;name&#xff0c;age --> <?…

【C/C++】C/C++编程——第一个 C++ 程序:HelloWorld

第一个 C 程序&#xff1a;HelloWorld 大家好&#xff0c;我是 shopeeai&#xff0c;也可以叫我虾皮&#xff0c;中科大菜鸟研究生。昨天我们成功搭建好了 C 的开发环境&#xff0c;今天我们来介绍一下第一个 C 程序,打印一个"hello world"。首先我们先贴一下示例代…

【FPGA Verilog开发实战指南】初识Verilog HDL-基础语法

这里写目录标题 Verilog HDL简介与VHDL比较 Verilog HDL基础语法逻辑值关键字moduleendmodule 模块名输入信号输出信号既做输入也做输出线网型变量 wire寄存器型变量 reg参数 parameter参数 localparam常量赋值方式阻塞赋值非阻塞赋值 always语句assign 语句 算数运算符归元运算…

C++ Qt day2

自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show() #include <io…

翻译: 使用 GPT-4 将您的 Streamlit 应用程序提升到一个新的水平一

帮助您更快地设计、调试和优化 Streamlit 应用的专业技巧 设计和扩展 Streamlit 应用程序可能是一项艰巨的任务&#xff01;作为开发人员&#xff0c;我们经常面临一些挑战&#xff0c;例如设计良好的 UI、快速调试我们的应用程序以及快速制作它们。 如果有一个工具可以加快速…

Tomcat运维

目录 一、Tomcat简介 二、系统环境说明 1、关闭防火墙&#xff0c;selinux 2、安装JDK 3、安装Tomcat 三、Tomcat目录介绍 1、tomcat主目录介绍 2、webapps目录介绍 3、Tomcat配置介绍&#xff08;conf&#xff09; 4、Tomcat的管理 四、Tomcat 配置管理页面(了解) …

类和对象 第三部分第三小节:const修饰成员函数

一.常函数&#xff1a; &#xff08;一&#xff09;成员函数后面加const后我们成这个函数为常函数 &#xff08;二&#xff09;常函数内不可以修改成员函数属性 额外补充&#xff1a; this指针的本质&#xff0c;是指针常量&#xff0c;指针指向的是不可以修改的 但是指针指向的…

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例4-11 HTML5 表单验证

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>HTML5 表单验证</title> </head><body> <form action"#" method"get" novalidate>请输入您的邮箱:<input type&q…

无限学模式-“科研创新的加速器:全面掌握ChatGPT,推动研究方法和工作模式现代化!“

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

小型商用机器人,如何做到小而强?

兼顾体型和性能。 体型和性能的矛盾 一直以来&#xff0c;商用清洁机器人的应用场景主要集中在大型商场、超市、写字楼等&#xff0c;为什么1000平米以下的小型商超等中小场景却很少涉足&#xff1f;原因可以说有很多&#xff0c;但核心为两方面&#xff0c;一方面&#xff0…

YOLOv8优化策略:注意力涨点系列篇 | 一种轻量级的加强通道信息和空间信息提取能力的MLCA注意力

🚀🚀🚀本文改进:一种轻量级的加强通道信息和空间信息提取能力 MLCA注意力 🚀🚀🚀在YOLOv8中如何使用 1)作为注意力机制使用;2)与c2f结合使用; 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研…

PaddleOCR将自己训练的模型转换为openvino格式模型

1 训练模型 python train_steelseal_det.py2 checkpoints模型转换为inference 模型 加载配置文件ch_PP-OCRv4_det_student_steelseal.yml&#xff0c;从./output/ch_PP-OCRv4/best_model/目录下加载model模型&#xff0c;inference模型保存在./output/ch_PP-OCRv4/best_model…

机器学习 | 深入探索Numpy的高性能计算能力

目录 初识numpy numpy基本操作 数组的基本操作 ndarray运算 数组间运算 矩阵 初识numpy Numpy&#xff08;Numerical Python&#xff09;是一个开源的Python科学计算库&#xff0c;用于快速处理任意维度的数组。Numpy支持常见的数组和矩阵操作。对于同样的数值计算任务&…

视频尺寸魔方:分层遮掩3D扩散模型在视频尺寸延展的应用

▐ 摘要 视频延展(Video Outpainting)是对视频的边界进行扩展的任务。与图像延展不同&#xff0c;视频延展需要考虑到填充区域的时序一致性&#xff0c;这使得问题更具挑战性。在本文中&#xff0c;我们介绍了一个新颖的基于扩散模型的视频尺寸延展方法——分层遮掩3D扩散模型(…

盛况空前 火热来袭 ▏2024上海国际轴承及其专用装备展览会暑期归来

中国设备管理协会主办的“2024上海国际轴承及其专用装备展览会”将于2024年7月24日至26日在“国家会展中心&#xff08;虹桥&#xff09;”举办。展会预计展出面积55000平方米&#xff0c;汇聚来自世界各地的近1000家企业与60000多人次的国内外观众齐聚一堂。为期三天的展览会是…

VisualSVN Server下载安装和使用方法、服务器搭建、使用TortoiseSvn将项目上传到云端服务器、各种错误解决方法

VisualSVN Server下载安装和使用方法、服务器搭建、使用TortoiseSvn将项目上传到云端服务器、各种错误解决方法 0.写在前面00.电脑配置01.思路 1.VisualSVN Server下载安装01.下载02.安装03.电脑命名不能有中文04.制作VisualSVN Server快捷方式05.License limits exceeded, Som…

仅用2天就备案完成了,这速度也太快了...

引言 大家好&#xff0c;就在前天&#xff0c;笔者才发布了文章《时隔78天&#xff0c;个人微信小游戏内容审核终于通过了&#xff0c;这到底是经历了什么…》。 感慨了游戏内容审核的不容易&#xff0c;同时简单介绍了备案的流程。 没想到申请备案才2天&#xff0c;就已经过…