一、反向迭代器概述
基础回顾:普通迭代器通过 ++ 操作从起始位置移动到尾后位置,实现正向遍历;
反向迭代器的核心定位:基于普通迭代器封装的'反向遍历工具',无需修改容器本身,就能实现从容器末尾到起始位置的遍历,接口与普通迭代器保持一致(支持 ++、*、== 等操作),适配双向/随机访问容器。
最基础的使用示例(仅作快速关联,不展开讲解,重点看后续原理):
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
// 反向遍历:从最后一个元素(5)到第一个元素(1)
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
cout << *it << " "; // 输出:5 4 3 2 1
}
return 0;
}
关键提醒:反向迭代器不是'全新迭代器',也不是普通迭代器的'反向操作',而是对普通迭代器的封装——这是理解其原理的核心前提。
二、核心原理:反向迭代器的设计思路
很多开发者使用反向迭代器时,只知 rbegin() 和 rend() 的用法,却不懂其设计初衷,导致踩坑不断。这里从'为什么这么设计'切入,拆解核心思路。
1. 设计目标:复用性 + 接口一致性
STL 中不同容器(vector、list、map)的普通迭代器,已经实现了各自的遍历逻辑(适配底层存储结构)。
反向迭代器的设计目标,就是不重复造轮子:
- 不单独为每个容器重新实现反向遍历逻辑,而是封装容器自带的普通迭代器(称为'基迭代器');
- 通过'反向映射',让反向迭代器的 ++ 操作,等价于普通迭代器的 -- 操作,保持与普通迭代器一致的接口;
- 最终实现:一套反向迭代器逻辑,适配所有支持 -- 操作的普通迭代器(双向、随机访问迭代器)。
2. 核心逻辑:反向映射的底层逻辑
用一个简单的 vector{1,2,3,4,5},直观理解反向迭代器与普通迭代器的映射关系: 普通迭代器的区间:[begin(), end()) → 指向 1 → 逐步 ++ → 指向尾后位置(5 后面); 反向迭代器的区间:[rbegin(), rend()) → 指向 5 → 逐步 ++ → 指向 1 前面的位置;
两者的核心映射关系(重中之重):
- 反向迭代器的 ++(向前移动一位,指向前一个元素) → 底层调用基迭代器的 --(向后移动一位);
- 反向迭代器的 --(向后移动一位,指向后一个元素) → 底层调用基迭代器的 ++(向前移动一位);


