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

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

Примеры были бы адаптированы.

- Jon

22
задан Peter Alexander 24 March 2010 в 19:33
поделиться

8 ответов

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

  1. filter_iterator, который вернул только отфильтрованное подмножество элементов в контейнере.
  2. Итератор выбора, который вернул только часть объекта.
  3. ostream_iterator, который ставит разделители до или между элементами, а не после них.
7
ответ дан 29 November 2019 в 05:40
поделиться

Единственный раз, когда я писал итераторы на C ++, помимо фильтров и итераторов, я пытался заставить классы контейнеров сторонних производителей хорошо работать с алгоритмами stl. Например

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

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

1
ответ дан 29 November 2019 в 05:40
поделиться

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

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

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

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

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

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

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

2
ответ дан 29 November 2019 в 05:40
поделиться

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

  • Для вашего собственного класса-контейнера (как вы сами указываете).
  • Итератор с пользовательским поведением для существующего класса контейнера. В STL, например, есть обратные итераторы. Может быть, вы хотите every_3rd_iterator, который возвращает только каждый третий элемент? Такой итератор, вероятно, будет реализован как адаптер вокруг существующего итератора.
1
ответ дан 29 November 2019 в 05:40
поделиться

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

0
ответ дан 29 November 2019 в 05:40
поделиться

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

2
ответ дан 29 November 2019 в 05:40
поделиться

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

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

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

5
ответ дан 29 November 2019 в 05:40
поделиться

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

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

3
ответ дан 29 November 2019 в 05:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: