反向迭代器有一个坑点。正向迭代器,指向的位置和解引用对应的元素是一致的;反向迭代器指向的位置和解引用对应的元素差了一个。从前往后看(正向角度),反向迭代器指向位置i,那么解引用会得到i-1位置上的元素。
cpprefrence指出,
For a reverse iterator
r
constructed from an iteratori
, the relationship&*r == &*(i - 1)
is always true (as long asr
is dereferenceable); thus a reverse iterator constructed from a one-past-the-end iterator dereferences to the last element in a sequence.
This is due to the fact that a reverse iterator has a slightly different referencing logic than a regular iterator: it points to an element, but when dereferenced, it yields a reference to the previous element.
更多参考:
- c++ - Why does removing the first element of a list invalidate
.rend()
? - Stack Overflow - c++ - Why can I not convert a reverse iterator to a forward iterator? - Stack Overflow
- c++ - Can I convert a reverse iterator to a forward iterator? - Stack Overflow
反向迭代器的base
成员函数,返回底层所持有的正向迭代器,我们转正向迭代器的时候尤其要注意上面的坑点,
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
int main() {
int i[] = {1,2,3,4,5,6};
std::vector<int> v(i, i+6);
auto ri = std::find(std::rbegin(v), std::rend(v), 3);
std::cout << *ri << std::endl; // 3
auto fi = ri.base()-1;
std::cout << *fi << std::endl; // 3
fi = (++ri).base();
std::cout << *fi << std::endl; // 3
}
即,
- 要么调用base之前将反向迭代器增一
- 要么调用base之后将得到的正向迭代器减一