Каковы недостатки std :: reverse_iterator? - PullRequest
18 голосов
/ 09 июля 2010

Документация для специализированных адаптеров итератора boost гласит, что boost::reverse_iterator "Исправляет многие недостатки в std :: reverse_iterator C ++ 98."

Что это за недостатки? Я не могу найти описание этих недостатков.

СЛЕДУЮЩИЙ ВОПРОС:

Как boost :: reverse_iterator исправляет эти недостатки?

1 Ответ

11 голосов
/ 09 июля 2010

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

  1. Некоторые версии erase() и insert() требуют итераторов, а не обратных итераторов.Это означает, что если вы используете обратные итераторы и хотите insert() или erase(), вам придется использовать функцию base() обратного итератора, чтобы получить прямой итератор.Автоматическое преобразование отсутствует.

  2. base() возвращает прямой итератор, эквивалентный обратному итератору с точки зрения вставки.То есть вставьте вставки перед текущим элементом.Следовательно, элемент, на который указывает обратный итератор, был бы неправильным элементом для указания, если бы base() дал вам итератор, который указал на тот же элемент.Таким образом, он указывает на один шаг вперед, и вы можете использовать его для вставки.

  3. Поскольку base() возвращает итератор, указывающий на другой элемент, это неправильный элемент для использования для erase(),Если вы вызвали erase() на итераторе из base(), вы удалили бы один элемент вперед в контейнере из элемента, на который указывает обратный итератор, поэтому вы должны увеличить обратный итератор перед вызовом base(), чтобыполучить правильный прямой итератор для erase().

  4. Можно ли даже использовать base() с erase() для правильного удаления элемента, полностью зависит от вашей реализации.Он работает с gcc, но с Visual Studio они на самом деле просто оборачивают прямой итератор таким образом, чтобы он не работал с erase() при работе с обратными итераторами и Visual Studio.Я не помню, имеет ли insert() ту же проблему, но обратные итераторы не работают одинаково между различными реализациями C ++ (по мнению ребят из Visual Studio, стандарт не был достаточно ясен), поэтому он может быть добрымволосатый, чтобы использовать их для чего-то кроме простой итерации по контейнеру.

Возможно, есть и другие проблемы, но они имеют дело с любым типом итератора, кроме неконстантного, forwardИтератор в C ++ при выполнении чего-либо, кроме простой итерации по контейнеру, может стать немного затруднительным - если вы даже можете сделать все это - потому что для многих функций требуются неконстантные итераторы прямого типа, а не какой-либо другой тип итератора.

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

РЕДАКТИРОВАТЬ: Что касается того, как обратный итератор Boost исправляет эти недостатки, я боюсь, что у меня нет подсказки.Я знаю о некоторых недостатках стандартного обратного итератора и был ими укушен в прошлом, но я никогда особо не использовал Boost, поэтому я совсем не знаком с их обратными итераторами.К сожалению.

...