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