0

0

c++中如何使用std::reverse_iterator反向遍历容器_c++迭代器技巧【汇总】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-17 00:15:18

|

371人浏览过

|

来源于php中文网

原创

std::reverse_iterator 是普通迭代器的包装,无需手动构造;推荐用 auto it = vec.rbegin() 遍历,其 * 和 -> 操作底层迭代器减一位置,base() 返回比当前反向位置多一位的原始迭代器。

c++中如何使用std::reverse_iterator反向遍历容器_c++迭代器技巧【汇总】

std::reverse_iterator 不是独立类型,而是对普通迭代器的包装;直接用 rbegin()rend() 就够了,手动构造 std::reverse_iterator 多数时候画蛇添足。

反向遍历容器最简写法:用 rbegin/rend 配合 auto

所有标准容器(std::vectorstd::liststd::deque 等)都提供 rbegin()rend() 成员函数,返回 std::reverse_iterator 类型,但你完全不需要显式写出这个类型名。

推荐写法:

for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
    std::cout << *it << " ";
}

注意:rend() 指向的是「逻辑上的第一个元素前一个位置」,即反向遍历时的结束哨兵,不是容器开头;它解引用是未定义行为。

立即学习C++免费学习笔记(深入)”;

  • rbegin() 等价于 std::reverse_iterator(end())
  • rend() 等价于 std::reverse_iterator(begin())
  • 不要对 rend() 调用 *itit->

什么时候必须显式写 std::reverse_iterator?

只有两种典型场景需要手动指定类型:

  • 函数模板参数推导失败,需显式传入迭代器类型(如某些算法适配)
  • 声明成员变量或函数返回类型时,接口契约要求明确类型(少见)

例如,给 std::binary_search 传反向迭代器时,如果容器是 const 的,rbegin() 返回 const_reverse_iterator,而你可能需要统一成非 const 版本:

AdMaker AI
AdMaker AI

从0到爆款高转化AI广告生成器

下载
std::vector v = {1,2,3,4,5};
auto rit = std::reverse_iterator(v.end()); // 显式构造,绕过 const 推导

但更常见且安全的做法是:先确保容器非常量,或直接用 std::vector::reverse_iterator 声明。

reverse_iterator 解引用和 operator-> 的行为陷阱

std::reverse_iterator*-> 实际操作的是它内部封装的「底层迭代器减一后的位置」。这意味着:

  • 底层迭代器必须支持 --(即不能是 std::forward_list::iterator —— 它不支持反向遍历)
  • std::vectorstd::string 这类随机访问容器,reverse_iterator 也是随机访问的;但对 std::list,它只是双向迭代器
  • it.base() 返回它封装的原始迭代器,但该值比当前反向位置「多一位」:即 rit.base() == next(rit)(逻辑上)

误用 base() 是高频错误:

std::vector v = {10,20,30};
auto rit = v.rbegin();
// 错!下面这行打印的是 20,不是 30
std::cout << *(rit.base()) << "\n"; // base() 指向 end(),解引用非法
// 正确获取对应正向位置:rit.base() - 1
std::cout << *(rit.base() - 1) << "\n"; // 输出 30

替代方案:C++20 范围库让反向遍历更直观

如果你用 C++20,std::ranges::reverse_view 更自然,也避免手写迭代器边界:

for (int x : std::ranges::reverse_view{vec}) {
    std::cout << x << " "; // 直接按反向顺序取值
}

它不暴露迭代器,无 rbegin/rend 边界匹配风险,也不依赖容器是否支持 reverse_iterator(只要支持 begin/end 即可)。但注意:它生成的是视图,不拷贝数据;若原容器生命周期短于循环,会悬垂。

真正容易被忽略的一点:反向迭代器的性能开销几乎为零(只是包装指针或整数),但它的语义容易让人误以为“自动优化了遍历路径”——其实它只是把正向逻辑翻转了一遍,底层移动仍是逐个 --+= -1。别指望它比正向快,也别在 std::forward_list 上强用它(编译不过)。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1465

2023.10.24

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

523

2023.09.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

538

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1020

2023.10.19

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

9

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 6.8万人学习

C 教程
C 教程

共75课时 | 4万人学习

C++教程
C++教程

共115课时 | 12.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号