Подтвердить что ты не робот

Когда писать итератор?

Я знаю, что это, наверное, глупый вопрос. Когда мне нужно будет написать свой собственный итератор? Это просто при разработке моего собственного класса контейнеров? Есть ли другие времена, когда я хотел бы создать свой собственный итератор?

Присваиваются примеры.

-Jon

4b9b3361

Ответ 1

Да, есть другие времена. Для нескольких примеров:

  • Фильтр-идентификатор, который возвращает только отфильтрованное подмножество элементов в контейнере.
  • Выбрать итератор, который возвращает только часть объекта.
  • Ostream_iterator, который помещает разделители до или между элементами, а не после них.

Ответ 2

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

Часто вы используете итераторы для перемещения контейнеров, но это далеко не единственное использование.

Итератор может также пересекать результаты запроса к базе данных, или ввод, считанный из потока (std::istream_iterator и std::istreambuf_iterator уже делает это, однако), или, возможно, вам нужен специальный порядок или стратегия обхода. Возможно, вы хотите перебрать "каждый член этого вектора, индекс которого делится на четыре" или "каждая заглавная буква в этой строке" или что-то еще, о чем вы можете думать.

Ответ 3

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

Это еще более верно, когда у вас есть семейство классов (опять же, скорее всего, контейнеры), и вы хотите предоставить своим пользователям единый интерфейс итерации/обхода для всех из них, даже если их реализация сильно отличается ( т.е. связанный список по отношению к массиву).

Ответ 4

Вам нужно написать собственный итератор для своего собственного класса контейнера или если вам требуется нестандартное поведение при повторении через стандартные контейнеры.

Ответ 5

Реализация итераторов может быть чрезвычайно полезной, и я делал это довольно часто. Итератор - это простая концепция, в которой все знают, как использовать. Итераторы позволяют использовать алгоритмы STL.

Часто вы можете реализовать итераторы для упрощения использования часто используемых API-интерфейсов операционной системы, таких как Windows FindNextFile

Когда вы пишете file_iterator (уже существует в boost), вы можете сделать следующее:

file_iterator itBegin; // initialize appropriately
file_iterator itEnd;
std::vector< HANDLE > vecFiles( itBegin, itEnd );

чтобы получить список дескрипторов для всех совпадающих файлов. Без итератора необходимые вызовы API сделали бы ваш код более трудным для чтения.

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

Если у вас есть двумерная структура, например. std::vector < std::vector > , другими словами, таблица, в которой каждый внутренний вектор должен иметь одинаковую длину, вам может потребоваться перебрать каждый n-й элемент внутренних векторов. Если это происходит достаточно часто, ваш код может стать намного проще при реализации итератора вместо того, чтобы распространять вложенные петли для всего кода.

Ответ 6

Я вижу два случая, когда вы хотели бы создать новый итератор:

  • Для вашего собственного класса контейнера (как вы указываете сами).
  • Итератор с пользовательским поведением для существующего класса контейнера. Например, STL имеет обратные итераторы. Может быть, вам нужен every_3rd_iterator, который возвращает только каждый третий элемент? Такой итератор, вероятно, будет реализован как адаптер вокруг существующего итератора.

Ответ 7

Помимо фильтров и итераторов выбора, единственный раз, когда я писал итераторы в С++, нужно, чтобы классы сторонних контейнеров играли хорошо с stl-алгоритмами. Например

  • Итератор с произвольным доступом для последовательности CORBA
  • Задний вставщик для последовательности CORBA
  • Двунаправленный итератор для XML Dom, это преобразовал dom node в итератор, который позволил мне использовать foreach и преобразовать на узлах братья и сестры.

В общем, мне не нравится писать итераторы, потому что они трудные, есть много вещей, о которых нужно позаботиться. Однако эта задача значительно упрощается благодаря библиотеке итераторов boost.

Ответ 8

Вы также можете использовать их для итерации по числовым последовательностям, таким как числа Фибоначчи или, возможно, простые числа. Это можно сделать другими способами, возможно, более легко, но могут быть случаи, когда использование итератора для таких вещей имеет смысл.