Посмотреть следующий элемент в контейнере STL - PullRequest
17 голосов
/ 09 сентября 2010

возможно ли просмотреть следующий элемент в контейнере, на который в данный момент указывает итератор, не изменяя его?

Например, в std :: set,

int myArray[]= {1,2,3,4};
set <int> mySet(myArray, myArray+4);
set <int>::iterator iter = mySet.begin();

//peek the next element in set without changing iterator.

mySet.erase(iter); //erase the element if next element is n+1

Ответы [ 6 ]

25 голосов
/ 09 сентября 2010

C ++ 0x добавляет удобную служебную функцию std::next, которая копирует итератор, продвигает его и возвращает расширенный итератор.Вы можете легко написать свою собственную std::next реализацию:

#include <iterator>

template <typename ForwardIt>
ForwardIt next(ForwardIt it, 
               typename std::iterator_traits<ForwardIt>::difference_type n = 1)
{
    std::advance(it, n);
    return it;
}

Вы можете использовать это в своем примере следующим образом:

if (iter != mySet.end() && next(iter) != mySet.end() && *next(iter) == *iter + 1)
    mySet.erase(iter);
15 голосов
/ 09 сентября 2010

Не с итераторами вообще. Итератор не гарантированно сможет работать неразрушающе. Классическим примером является Итератор ввода, который фактически представляет основной входной поток.

Есть кое-что, что работает для такого рода итераторов. Forward Iterator не делает недействительными предыдущие копии самого себя, продвигаясь вперед по коллекции. Большинство итераторов (в том числе и для коллекций STL) являются по крайней мере прямыми итераторами, если не являются более функциональными входными итераторами только для версий или выходными итераторами, которые более ограничены. Таким образом, вы можете просто сделать копию своего итератора, увеличить его и проверить , что , а затем вернуться к исходному итератору.

Итак, ваш заглядывающий код:

set <int>::iterator dupe = iter;
++dupe;
// (do stuff with dupe)
3 голосов
/ 09 сентября 2010
set <int>::iterator iter2 = iter;
++iter2;
int peekedValue = *iter2;
0 голосов
/ 09 сентября 2010

Это не будет работать для std::set, поскольку его природа не допускает оператора [], но для контейнеров, которые это делают, вы можете сделать:

std::vector<int> v;
v.push_back(3);
v.push_back(4);
std::vector<int>::iterator it = v.begin(); 
std::cout << v[it - v.begin() + 1];

Но это может быть опасно, если it указывает на последний элемент в контейнере;но то же самое относится и к решению выше.Например, вам придется проверять в обоих случаях.

0 голосов
/ 09 сентября 2010

для контейнеров последовательностей (vector, deque и list) вы можете вызвать front, что даст вам возможность взглянуть (больше информации в нижней части этой ссылки ).

0 голосов
/ 09 сентября 2010

Вы всегда можете сделать копию итератора и продвинуть копию:

set <int>::iterator iter = mySet.begin();
set <int>::iterator iterCopy = iter;
iterCopy++;
if (*iterCopy == something)
  mySet.erase(iter);

Но учтите, что iterCopy может перестать действовать после того, как вы сотрете iter.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...