【C++11 之rbegin()、rend() 反向迭代器原理介绍及 重点-限制情况】与正向迭代器对比(互换放在下一p)

C++11 引入了许多新特性,其中包括对 STL(Standard Template Library)的改进。在 STL 容器中,rbegin() 和 rend() 是两个新的成员函数,它们分别返回指向容器最后一个元素的反向迭代器(reverse iterator)和指向容器“理论上的前一个元素”的反向迭代器(该迭代器实际上并不指向任何有效元素,而是作为结束标记)。

反向迭代器介绍

反向迭代器是一种特殊的迭代器,它允许我们按照与正向迭代器相反的顺序遍历容器。也就是说,如果我们使用正向迭代器从容器的开始遍历到结束,那么使用反向迭代器就是从容器的结束遍历到开始。

使用场景

反向迭代器在需要逆序遍历容器元素的场景中非常有用。例如,你可能想要从后向前检查一个字符串是否以某个子串结尾,或者你可能想要逆序打印一个向量的所有元素。

与正向迭代器原理对比

正向迭代器和反向迭代器在原理上的主要区别在于它们如何定义“下一个”元素。对于正向迭代器,++it 将迭代器向前移动到下一个元素;而对于反向迭代器,++it 将迭代器向后移动到“上一个”元素。注意,这里的“上一个”和“下一个”是相对于容器的遍历方向而言的。

代码对比

以下是使用正向迭代器和反向迭代器遍历 std::vector 的示例代码:

#include <iostream>  
#include <vector>  
  
int main() {  
    std::vector<int> v = {1, 2, 3, 4, 5};  
  
    // 使用正向迭代器遍历  
    for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {  
        std::cout << *it << ' ';  
    }  
    std::cout << '\n';  
  
    // 使用反向迭代器遍历  
    for (std::vector<int>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit) {  
        std::cout << *rit << ' ';  
    }  
    std::cout << '\n';  
  
    return 0;  
}

在这个示例中,我们首先使用正向迭代器从前往后遍历 vector,然后使用反向迭代器从后往前遍历 vector。输出将是:

1 2 3 4 5   
5 4 3 2 1

注意,虽然正向迭代器和反向迭代器在语法上有所不同(特别是它们的类型),但它们的用法非常相似:都可以使用 * 运算符来解引用迭代器以访问元素,都可以使用 ++ 运算符来移动迭代器,等等。

看完你会发现反向迭代器其实也没有太多特殊的。是的,但反向迭代器本身设置了很多的限制,所以认识反向迭代器,我们一定要熟悉其限制机制;

重点-限制情况

  1. 依赖双向迭代器:
    反向迭代器通常基于容器的双向迭代器实现。因此,如果容器仅支持单向迭代器(如某些输入迭代器),则无法使用反向迭代器。
    这意味着反向迭代器不能用于如 std::istream_iterator 这样的单向迭代器类型。
  2. 特定操作不可用:
    反向迭代器不支持随机访问迭代器的某些操作,如 operator+=、operator+、operator-=、operator- 和 operator[]。这是因为反向迭代器的内部机制并不直接支持这些操作。
    例如,你不能直接通过 rit + 3 来跳过三个元素(其中 rit 是一个反向迭代器),因为这需要知道“理论上的前一个元素”的位置,这在反向迭代器的上下文中是不可知的。
  3. 引用和指针的语义:(这个难以理解就在下一p中熟悉-C++17新特性)
    反向迭代器的 &*rit(取反向迭代器 rit 指向元素的地址)操作与正向迭代器有所不同。在反向迭代器的上下文中,&*rit 实际上引用的是迭代器在原有序列中引用的元素之外(右侧)一个位置的元素。
    这意味着你不能直接通过反向迭代器来获取容器中元素的原始地址(除非你使用额外的逻辑来转换它)。
  4. 迭代器的有效性:
    反向迭代器的有效性同样受到容器修改操作的影响。如果在遍历过程中修改了容器的大小(如添加或删除元素),则可能导致反向迭代器失效。
    需要注意的是,即使正向迭代器在容器修改后仍然有效,其对应的反向迭代器也可能不再有效。
  5. 类型差异:
    反向迭代器的类型与正向迭代器的类型不同。在 C++ 中,你需要使用如 std::vector::reverse_iterator 这样的类型来声明反向迭代器。
    这意味着你不能直接将正向迭代器赋值给反向迭代器,或者期望它们在类型上兼容。
  6. 使用场景限制:
    虽然反向迭代器在处理需要逆序遍历容器的场景时非常有用,但它们并不适用于所有情况。在某些情况下,使用正向迭代器可能更加直观和高效。

归纳来说,反向迭代器的限制主要源于其基于双向迭代器的设计和实现方式,以及与正向迭代器的差异。这些限制在使用反向迭代器时需要特别注意,以避免潜在的问题和错误。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CleanMyMac占用内存大吗 CleanMyMac如何释放内存空间

Mac OS上内存可谓是“寸土寸金”&#xff0c;每一M的内存都是真金白银换来的。为了有更充足的系统空间&#xff0c;有用户会使用系统清理和优化工具CleanMyMac&#xff0c;那么下面我们来看看CleanMyMac占用内存大吗&#xff0c;CleanMyMac如何释放内存空间的相关内容吧。 一、…

spring boot配置ssl证书,支持https访问

1. 阿里云官网下载证书,云控制台搜索ssl&#xff0c;点击进入。 2.点击免费证书&#xff0c;立即购买。 3. 点击创建证书&#xff0c;填写完证书申请后&#xff0c;等待证书签发。 4. 证书签发以后&#xff0c;点击下载证书&#xff0c;spring boot选tomcat服务器类型的。 5. …

Linux应用编程 - i2c-dev操作I2C

嵌入式Linux操作I2C设备&#xff0c;我们一般会在内核态编写I2C驱动程序。另外还能在用户空间编写I2C程序&#xff0c;下面介绍相关代码的实现。 i2c-dev框架在内核中封装了I2C通信所需要的所有通信细节&#xff0c;I2C适配器会在/dev目录下创建字符设备&#xff0c;例如&#…

如何避免销售飞单私单!教你如何巧妙避开陷阱,业绩飙升!

明明投入了大量的时间和精力&#xff0c;客户却悄无声息地消失了&#xff1f;或是突然有一天&#xff0c;你发现原本属于你的订单被同事悄悄抢走&#xff1f;这背后&#xff0c;很可能隐藏着销售飞单私单的陷阱。今天&#xff0c;就让我们一起探讨如何巧妙避开这些陷阱&#xf…

TCP与UDP案例

udp不会做拆分整合什么的 多大就是多大

MyBatis使用Demo

文章目录 01、Mybatis 意义02、Mybatis 快速入门04、Mapper 代理开发05、Mybatis 配置文件07、查询所有&结果映射08、查询-查看详情09、查询-条件查询10、查询-动态条件查询多条件动态查询单条件动态查询 11、添加&修改功能添加功能修改功能 12、删除功能删除一个批量删…

【html】学会这一套布局,让你的网页更加

很多小伙伴们在刚刚开始学习网页设计的时候不知道怎么布局今天给大家介绍一种非常实用且更加专业的一种布局。 灵感来源&#xff1a; 小米官网 布局图; 实例效果图&#xff1a; 这是一个简单的HTML模板&#xff0c;包括头部、内容区域和底部。 头部部分包括一个分为左右两部分…

【记录】ChatGLM3-6B大模型部署、微调(二):微调

前言 上文记录了ChatGLM3-6B大模型本地化部署过程&#xff0c;本次对模型进行微调&#xff0c;目的是修改模型自我认知。采用官方推荐微调框架&#xff1a;LLaMA-Factory 安装LLaMA-Factory # 克隆项目 git clone https://github.com/hiyouga/LLaMA-Factory.git 安装依赖 # 安装…

Linux---系统的初步学习【项目一:Linux操作系统的安装与配置】

项目一 Linux操作系统的安装与配置 1.1 项目知识准备 1.1.1 操作系统是什么&#xff1f; ​ 操作系统&#xff08;Operating System&#xff0c;OS&#xff09;是管理计算机硬件与软件资源的计算机程序。操作系统需要处理如管理硬件、决定程序运行的优先次序、管理文件系统等…

逻辑斯蒂回归与最大熵

知识树 感知机的缺陷 修补感知机缺陷-逻辑斯蒂回归 下面这两个值是强制给的,不是推导的 最大熵 最大熵的一个小故事 最大熵模型 我们最终目标是要求P(Y|X) 书上写的是H,但是2我们认为H(Y|X)更合适 咱们最终的目的是要用拉格朗日乘数法,所以需要约束 总结 感觉深度之眼比较模…

汽车级TPSI2140QDWQRQ1隔离式固态继电器,TMUX6136PWR、TMUX1109PWR、TMUX1133PWR模拟开关与多路复用器(参数)

1、TPSI2140-Q1 是一款隔离式固态继电器&#xff0c;专为高电压汽车和工业应用而设计。 TPSI2140-Q1 与 TI 具有高可靠性的电容隔离技术和内部背对背 MOSFET 整合在一起&#xff0c;形成了一款完全集成式解决方案&#xff0c;无需次级侧电源。 该器件的初级侧仅由 9mA 的输入电…

Studio One 6.6.2 for Mac怎么激活,有Studio One 6激活码吗?

如果您是一名音乐制作人&#xff0c;您是否曾经为了寻找一个合适的音频工作站而苦恼过&#xff1f;Studio One 6 for Mac是一款非常适合您的MacBook的音频工作站。它可以帮助您轻松地录制、编辑、混音和发布您的音乐作品。 Studio One 6.6.2 for Mac具有直观的界面和强大的功能…

Zookeeper: 配置参数解读

Zookeeper中的配置文件zoo.cfg中参数含义解读如下&#xff1a; tickTime&#xff1a;通信心跳时间&#xff0c;Zookeeper服务器与客户端心跳时间&#xff0c;单位毫秒。 initLimit: LF初始通信时限 Leader和Follower初始连接时能容忍的最多心跳数。 syncLimit: LF同步通信时…

算法01 递推算法及相关问题详解【C++实现】

目录 递推的概念 训练&#xff1a;斐波那契数列 解析 参考代码 训练&#xff1a;上台阶 参考代码 训练&#xff1a;信封 解析 参考代码 递推的概念 递推是一种处理问题的重要方法。 递推通过对问题的分析&#xff0c;找到问题相邻项之间的关系&#xff08;递推式&a…

mongodb 集群安装

1. 配置域名 Server1&#xff1a; OS version: CentOS Linux release 8.5.2111 hostnamectl --static set-hostname mongo01 vi /etc/sysconfig/network # Created by anaconda hostnamemong01 echo "192.168.88.20 mong1 mongo01.com mongo02.com" >> /…

用GAN网络生成彩票号码

1. 前言 生成对抗网络&#xff08;GAN&#xff0c;Generative Adversarial Network&#xff09;是由Ian Goodfellow等人在2014年提出的一种深度学习模型&#xff0c;用于学习和生成与真实数据分布相似的数据。GAN由生成器&#xff08;Generator&#xff09;和判别器&#xff08…

Python编程环境搭建

简介&#xff1a; Python环境安装比较简单&#xff0c;无需安装其它依赖环境&#xff0c;主要步骤为&#xff1a; 1. 下载并安装Python对应版本解释器 2. 下载并安装一个ide编码工具 一、下载并安装Python解释器 1.1 下载 官网地址&#xff1a;Welcome to Python.org 选择…

STM32-CAN

一、CAN总线简介 1.1 CAN简介 CAN 是 Controller Area Network 的缩写&#xff08;以下称为 CAN&#xff09;&#xff0c;是 ISO 国际标准化的串行通信 协议。异步半双工。 ISO11898&#xff1a;123kbps~1Mbps。 ISO11519&#xff1a;125kbps 特点&#xff1a; 多主控制没…

Dify源码本地部署启动

背景 Dify是一个开源LLM应用程序开发平台。Dify的直观界面结合了人工智能工作流、RAG管道、代理功能、模型管理、可观察性功能等&#xff0c;让您快速从原型到生产。 Dify提供在线试用功能&#xff0c;可以直接在线体验其功能。同时也支持docker部署&#xff0c;源码部署等方…

【Vue】Pinia管理用户数据

Pinia管理用户数据 基本思想&#xff1a;Pinia负责用户数据相关的state和action&#xff0c;组件中只负责触发action函数并传递参数 步骤1&#xff1a;创建userStore 1-创建store/userStore.js import { loginAPI } from /apis/user export const useUserStore defineStore(…