Когда написать итератор? - PullRequest
22 голосов
/ 24 марта 2010

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

Примеры будут присвоены.

-Jon

Ответы [ 8 ]

7 голосов
/ 24 марта 2010

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

  1. Filter_iterator, который возвращал только отфильтрованное подмножество элементов в контейнере.
  2. Итератор выбора, который возвратил только часть объекта.
  3. ostream_iterator, который помещает разделители перед или между элементами, а не после них.
5 голосов
/ 24 марта 2010

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

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

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

3 голосов
/ 24 марта 2010

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

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

2 голосов
/ 25 марта 2010

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

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

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

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

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

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

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

2 голосов
/ 24 марта 2010

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

1 голос
/ 24 марта 2010

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

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

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

1 голос
/ 24 марта 2010

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

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

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

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