2013-05-17 1 views
13

У меня есть такой код:C++ STL, что делает базу() делает

vector <int> v; 
for (int i=0; i<5; i++) 
     v.push_back(i); 
v.erase(find(v.rbegin(), v.rend(),2).base()); 

Этот код удаляет первый элемент из вектора V после того, как впервые обнаружено 2 (в векторе остается: 0 1 2 4). Что делает .base() здесь?

+0

Возможно, вам стоит прочитать следующее: http://www.cplusplus.com/reference/iterator/reverse_iterator/base/ – JBL

ответ

22

base() преобразует обратный итератор в соответствующий вперед итератора. Однако, несмотря на свою простоту, эта переписка не такая тривиальная, как одна вещь.

При обратном точки итератора на одном элементе, он разыменовывает предыдущий, поэтому он элемент физически указывает на элемент и он логически указывает на разные. На следующей диаграмме, i является прямым итератора, и ri является обратным итератора построена из i:

       i, *i 
          | 
    -  0  1  2  3  4  - 
         |  | 
         *ri ri 

Так что если ri логически указывает на элемент 2, он физически указывает на элемент 3. Поэтому при преобразовании в форвардный итератор результирующий итератор будет указывать на элемент 3, который будет удален в вашем примере.

Следующая небольшая программа демонстрирует выше поведение:

#include <iostream> 
#include <vector> 
#include <iterator> 
#include <algorithm> 

int main(int argc, char *argv[]) 
{ 
    std::vector<int> v { 0, 1, 2, 3, 4 }; 
    auto i = find(begin(v), end(v), 2); 

    std::cout << *i << std::endl; // PRINTS 2 

    std::reverse_iterator<decltype(i)> ri(i); 
    std::cout << *ri << std::endl; // PRINTS 1 
} 

Вот является live example.

8

base() возвращает базовый итератор базы.

Основание итератора относится к элементу, который находится рядом с элементом reverse_iterator данным момента указует. То есть std::reverse_iterator(it).base() == std::next(it).

Вы можете узнать больше о reverse_iteratorhere.

enter image description here