反向迭代器详解

stl中如何设计反向迭代器

反向迭代器顾名思义就是帮助容器从后向前遍历的一种迭代器,有const和非const版本区别,利用模板可以实现两种版本代码的复用

stl中反向迭代器的设计使用的是经典的适配器迭代器模式,意思是不自己从头写一遍,而是复用正向迭代器,利用正向迭代器实现的功能实现反向迭代器。

另外值得一提的是反向迭代器中的rbegin和rend和我们自以为的实现方式可能不同,也许是为了美观,反向迭代器的rbegin指向正向迭代器end指向的数据,而rend指向begin指向的数据。这就导致了如果我们要实现解引用操作符的重载,不能直接使用正向迭代器的解引用操作符重载,而是使用一个临时变量向前移动一步后返回这个变量指向的数据,不然可能会出现对某些容器哨兵位的非法访问,箭头操作符也面临同样的问题。需要对这两个特例单独操作。

stl反向迭代器解引用操作符代码:

_NODISCARD _CONSTEXPR17 reference operator*() const {_BidIt _Tmp = current;return *--_Tmp;}

stl反向迭代器箭头操作符代码:

_NODISCARD _CONSTEXPR17 pointer operator->() const {_BidIt _Tmp = current;--_Tmp;if constexpr (is_pointer_v<_BidIt>) {return _Tmp;} else {return _Tmp.operator->();}}

实现一个反向迭代器

先贴上正向迭代器的代码,反向迭代器的实现需要正向迭代器

 template<class T, class ref, class ptr>struct __list_iterator{typedef list_node<T> Node;typedef __list_iterator<T, ref, ptr> iterator;Node* node;__list_iterator(Node* node):node(node){}bool operator!=(const iterator& it) const{return node != it.node;}bool operator==(const iterator& it) const{return node == it.node;}ref operator*(){return node->data;}ptr operator->(){return &(operator*());}iterator operator++(){node = node->next;return *this;}iterator operator++(int){Node* tmp = node;node = node->next;return iterator(tmp);}iterator operator--(){node = node->prev;return *this;}iterator operator--(int){Node* tmp = node;node = node->prev;return iterator(tmp);}};

有了正向迭代器,实现反向迭代器就很简单了

 template<class iterator, class ref, class ptr>struct __list_reverse_iterator{iterator _it;typedef __list_reverse_iterator<iterator, ref, ptr> Reverse_iterator;__list_reverse_iterator(iterator it):_it(it){}bool operator!=(const Reverse_iterator& rit) const{return _it != rit._it;}bool operator==(const Reverse_iterator& rit) const{return _it == rit._it;}ref operator*(){iterator tmp = _it;return *(--tmp);}ptr operator->(){return &(operator*());}Reverse_iterator operator++(){--_it;return *this;}Reverse_iterator operator++(int){iterator tmp = _it;--_it;return Reverse_iterator(tmp);}Reverse_iterator operator--(){++_it;return *this;}Reverse_iterator operator--(int){iterator tmp = _it;++_it;return Reverse_iterator(tmp);}};

想要实现模板自动控制const迭代器和非const迭代器,只需要对迭代器类显式实例化时加上两个参数就可以完成

typedef __list_reverse_iterator<iterator, T&, T*> Reverse_iterator;
typedef __list_reverse_iterator<const_iterator,const T&,const T*>
const_Reverse_iterator;

总结

理论上只有迭代器能实现–操作就才能实现反向迭代器,因此一些单向容器是没有反向迭代器的,这种适配器迭代器模式极大的简化了代码,并且更加容易理解,是一种经典的设计模式。

反向迭代器(rbegin,rend)详解相关推荐

  1. C++ - const 与 迭代器(iterator) 使用 详解

    const 与 迭代器(iterator) 使用 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/16030561 迭代器(i ...

  2. http反向代理之haproxy详解

    1.反向代理定义 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求 ...

  3. std::string中的反向迭代器rbegin()和rend()

    在std::string中,有个接口是rbegin()和rend(),分别表示string字符串的倒数第一个字符和正数第一个字符: rbegin():表示string字符串的倒数第一个字符 rend( ...

  4. 利用Nginx实现负载均衡(反向代理)完全详解

    1.常见负载均衡的方式(概念普及) [1]用户手动选择 例如我们玩游戏,服务器会显示当前服务器的状态是拥挤.繁忙.还是空闲,然后用户根据自己实际需要,选择自己想去的服务器. 如果服务器人太多(达到上限 ...

  5. C++:迭代器(STL迭代器)iterator详解

    STL迭代器 参考链接:http://c.biancheng.net/view/338.html

  6. nndl学习笔记(二)反向传播公式推导与详解

    写在前面 反向传播回顾 为什么需要反向传播? 基本思想 算法流程 算法局限性 详细推导(核心:多元微积分的*链式法则*) 一些定义 1. 输出层的误差δL\delta^{L}δL 2. 利用下一层误差 ...

  7. nginx反向代理模块配置详解_Nginx服务器的反向代理proxy_pass配置方法讲解

    就普通的反向代理来讲 Nginx的配置还是比较简单的,如: location ~ /* { proxy_pass http://127.0.0.1:8008; } 或者可以 location / { ...

  8. nginx反向代理模块配置详解_Nginx(三):反向代理负载均衡集群配置详解

    概述: 本篇主要总结Nginx实现反向代理和负载均衡功能相关模块的配置说明.主要使用到的模块如下:ngx_http_proxy_moduleNginx实现反向代理功能 ngx_http_upstrea ...

  9. [js高手之路] es6系列教程 - 迭代器与生成器详解

    什么是迭代器? 迭代器是一种特殊对象,这种对象具有以下特点: 1,所有对象都有一个next方法 2,每次调用next方法,都会返回一个对象,该对象包含两个属性,一个是value, 表示下一个将要返回的 ...

  10. python全栈之巅_Python 迭代器、生成器详解 - Python全栈之巅

    迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退. 使用迭代器的优点 对于 ...

最新文章

  1. mysql 5.7 pxc_mysql5.7 PXC安装记录
  2. Oracle杀事务数据库崩溃,关于pl/sql dev窗口崩溃导致锁表
  3. python-temp-0626随堂
  4. PAC自动代理文件格式,教你如何写PAC文件
  5. database如何管理超过4GB的文件
  6. 智能风控建模全流程--看这篇就够了
  7. 不吹不黑,这5款浏览器安全无广告无弹窗,亲测好用
  8. (一)Activiti 数据库25张表——流程历史记录表20(ACT_HI_DETAIL)
  9. html录音并调用讯飞语音接口,微信小程序前台调用讯飞语音识别接口
  10. yii2 aliases web.php,Yii2的深入学习--别名(Aliases),yii2aliases
  11. PlayStation Now比您想象的要好
  12. 接外包有哪些渠道呢?
  13. 咸鱼笔记—Socket 通信
  14. oracle sql 字段值行 连乘,如何使用Oracle数据库将矩阵与其转置相乘,并使用utl_nla...
  15. 2020-09-28
  16. Lambda相关图形
  17. 威猛的 90 后,不等领导下班就先走,《2021 年轻人下班报告》公布
  18. AIX中 |SMIT/SMITTY| 的使用
  19. 【蜂言蜂语】何以解忧?唯有暴富~
  20. Hadoop_day04学习笔记

热门文章

  1. 四川省甘孜藏族自治州谷歌高清卫星地图下载
  2. 下载直播视频通用方法
  3. 到底绿茶能不能减肥瘦小肚子? - 健康程序员,至尚生活!
  4. ESP USB Camera 的应用方案
  5. 漏洞扫描--需要整改的
  6. 阿里云云盘根目录扩容
  7. 清爽好用的开源导航源码
  8. 智能增效,路路通软件为中金骨质瓷发展再添新动能!
  9. LR_脚本函数构成一:
  10. 超分辨率重建测试(ESRGAN)