手搓反向迭代器

前言

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

  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,一经查实,立即删除!

相关文章

列举MySQL对于Where子句的优化

列举MySQL对于Where子句的优化 在MySQL8之前&#xff0c;我们自己额外注意一些查询语句的写法&#xff0c;牺牲了代码的可读性。在MySQL8中&#xff0c;会自动进行类似的优化。可以保持查询的易理解性和可维护性。 这边文章会列举这些优化点。 查询语句优化 删除不必要的括号…

软件测试生命周期

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

Spring Boot + EasyExcel实现Excel文件导入导出

Java解析、生成Excel比较有名的框架有Apache poi、jxl等&#xff0c;使用者可自行斟酌。 一、 为什么使用 EasyExcel 1.1 内存控制 Apache poi、jxl也能解析Excel&#xff0c;但他们都存在一个问题就是非常的耗内存&#xff0c;poi有一套SAX模式的API可以一定程度的解决一些…

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 版本…

apache 前30个开源项目

由于Apache软件基金会的开源项目 前30个具有代表性的项目 序号项目名称功能描述业务范围活跃度&#xff08;参考性描述&#xff09;1Apache HTTP Server高性能Web服务器提供HTTP服务支持非常活跃2Apache TomcatJava应用服务器部署Java Web应用程序非常活跃3Apache Hadoop分布式…

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"。首先我们先贴一下示例代…

《WebKit技术内幕》学习之十三(2):移动WebKit

2 移动化用户界面 HTML5为移动领域做了大量的工作&#xff0c;其中“meta”标签中的众多设置值能够帮助提供非常好的移动用户体验。一个典型的例子就是上面提到的用该标签来控制网页缩放&#xff0c;如示例代码13-2使用了一些JavaScript代码来完成&#xff0c;而实际上&#x…

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

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

【C语言】分支循环语句

分支 if elseif else if else if elseswitch() case default 循环 while 防止死循环for 已知所需循环次数do while 至少执行一次 break 和continue在循环中的应用 break &#xff1a;退出当前循环&#xff1b; continue&#xff1a;推出本次/轮循环 goto 太乱了&#xff0c;不…

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;指针指向的是不可以修改的 但是指针指向的…

点击查看灯塔工厂

“灯塔工厂”项目由达沃斯世界经济论坛与管理咨询公司麦肯锡合作开展遴选&#xff0c;被誉为“世界上最先进的工厂”&#xff0c;是工业4.0技术应用的最佳实践工厂&#xff0c;代表着全球智能制造的最高水平。目前全球“灯塔工厂”共有 153 座&#xff0c;包含中国 62 座。 做…

响应式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…

工厂模式-策略工厂模式 两者的区别

模拟支付分为 微信支付 &#xff0c;支付宝支付&#xff0c;银联支付 1、工厂模式 &#xff08;1&#xff09;、支付枚举类 import lombok.Getter;/*** author zwh* date 2024/1/26*/ Getter public enum PayEnum {/*** 支付类型*/WX_PAY(1, "微信支付"),ALI_PAY(…