Why does removing the _first_ element of a list invalidate `.rend()`?

落爺英雄遲暮 提交于 2019-11-29 02:04:05

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!