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

后端 未结 1 1458
误落风尘
误落风尘 2020-12-16 01:35

Tested on Mac OS X using XCode 4.6.

This example code shows removing the last element of an std::list works as I expected: an iterator reference to

相关标签:
1条回答
  • 2020-12-16 02:17

    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.

    0 讨论(0)
提交回复
热议问题