I have the following code:
int main()
{
vector<int> v;
for(int i = 0; i < 10; ++i)
v.push_back(i);
auto it = v.begin() + 3;
cout << "Iterator: " << *it << endl;
vector<int>::reverse_iterator revIt(it);
cout << "Reverse iterator: " << *revIt << endl;
}
After running this code I get the following output:
Iterator: 3
Reverse iterator: 2
Could someone explain why the 2 values differ ?
Reverse iterators 'correspond' to a base iterator with an offset of one element because of how rbegin() and rend() have to be represented using base iterators that are valid (end() and begin() respectively). For example, rend() cannot be represented by an interator that 'points' before the container's begin() iterator, although that's what it logically represents. So rend()'s 'base iterator' is begin(). Therefore, rbegin()'s base iterator becomes end().
A reverse iterator automatically adjusts for that offset when it is dereferenced (using the * or -> operators).
An old article by Scott Meyers explains the relationship in detail along with a nice picture:
Guideline 3: Understand How to Use a reverse_iterator’s Base iterator
Invoking the base member function on a reverse_iterator yields the “corresponding” iterator, but it’s not really clear what that means. As an example, take a look at this code, which puts the numbers 1-5 in a vector, sets a reverse_iterator to point to the 3, and sets an iterator to the reverse_iterator’s base:
vector<int> v; // put 1-5 in the vector for (int i = 1; i <= 5; ++i) { v.push_back(i); } // make ri point to the 3 vector<int>::reverse_iterator ri = find(v.rbegin(), v.rend(), 3); // make i the same as ri's base vector<int>::iterator i(ri.base());After executing this code, things can be thought of as looking like this:
This picture is nice, displaying the characteristic offset of a reverse_iterator and its corresponding base iterator that mimics the offset of rbegin() and rend() with respect to begin() and end(), but it doesn’t tell you everything you need to know. In particular, it doesn’t explain how to use i to perform operations you’d like to perform on ri.
Looks like the documentation says they do that to handle past-the-end elements, i.e. if you reverse an iterator that is past the end, the new reverse iterator points to the last element.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With