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.
You will easily see this if you try the following:
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
vector<int> v = { 1, 2, 3, 4, 5, 6 };
auto i = find(begin(v), end(v), 3);
cout << *i << endl;
vector<int>::const_reverse_iterator ri(i);
cout << *ri << endl;
}
The output should be:
3
2
When a reverse iterator physically points to a certain element, it logically points to the element which precedes it. Thus, a reverse iterator physically pointing to the element in a collection with index i
, when dereferenced, yields (a reference to) the element with index i-1
:
i, *i
|
- 1 2 3 4 5 6 -
| |
*ri ri
This is the reason why an iterator return by rend()
actually points to the first element in a collection, and not to the one before the first element. Removing the first element, therefore, invalidates it.
begin, *begin end, *end
| |
- 1 2 3 4 5 6 -
| | | |
*rend rend *rbegin rbegin
This does not apply only to lists, but to all collections which offer bidirectional iterators.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…