Выглядеть следующий элемент в контейнере STL

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

Например, в 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

Ответы

Ответ 1

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

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

Итак, ваш код подписи:

set <int>::iterator dupe = iter;
++dupe;
// (do stuff with dupe)

Ответ 2

С++ 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);

Ответ 3

set <int>::iterator iter2 = iter;
++iter2;
int peekedValue = *iter2;

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

Это не будет работать для 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 указывает на последний элемент в контейнере; но то же самое относится к решению выше. Например. вам придется делать проверки в обоих случаях.