Base for reverse_iterator

We have a vector, a huge one, and we expect that an element we are looking for it is closer to its end than its beginning. So we perform a find() on the reversed vector, delimited by the reversed begin-end iterators, and we get back a reverse iterator pointing to the found element (or to the vector reverse end).

To use the reverse iterator we have to convert it to a straight one, by its base() member function. But you should pay attention to the context in which you are using it.

Here we have a vector and we perform a reverse find() looking for an element:

std::vector<int> vi;
vi.reserve(5);

for(int i = 0; i < 5; ++i)
vi.push_back(i);
dump(vi);

std::vector<int>::reverse_iterator rit = find(vi.rbegin(), vi.rend(), 3);

To insert a new element in the vector after the found, we pass the converted resulting reverse iterator to the insert() vector member function:
vi.insert(rit.base(), 99);
But if we want to erase the element we found we actually need to decrement the converted iterator before removing:

if(rit != vi.rend())
vi.erase(--rit.base());

If we forget to do that the unexpected result will be to remove the next element instead (in this case _4_ instead of _3_).

More on this topic in Effective STL Item 28. Have fun with the Effective C++ book series by Scott Meyers.

No comments:

Post a Comment