Стандартные контейнеры поддерживают две политики итерации с двумя типами итераторов: ::iterator
и ::reverse_iterator
.Вы можете выполнить преобразование между ними, используя конструктор std::reverse_iterator
и его функцию-член base()
.
. В зависимости от того, насколько похожи ваши политики итерации, может быть или не быть легко обеспечить преобразование в различные типы итераторов.,Идея состоит в том, что результат должен указывать на «эквивалентную позицию» в политике итерации типа назначения.Для обратных итераторов эта эквивалентность определяется тем, что если вы вставите в эту точку, результат будет таким же.Так, если rit
является обратным итератором, vec.insert(rit.base(), ...)
вставляет элемент «до» rit
в обратную итерацию , то есть после элемент, на который указывает rit
в контейнере.Это довольно неудобно, и будет только хуже, когда политики итерации полностью не связаны.Но если все ваши типы итераторов являются (или могут быть похожими) оболочками вокруг «нормального» итератора, охватывающего все элементы, то вы можете определить преобразования в терминах этой базовой позиции итератора.
Вы* на самом деле нужно преобразований, если есть функции-члены, которые добавляют или удаляют элементы контейнера, потому что вы, вероятно, не хотите предоставлять отдельную перегрузку для каждого типа итератора (так же, как стандартные контейнеры не делаютопределить insert
и erase
для обратных итераторов).Если итераторы используются исключительно для указания на элементы, то, скорее всего, вы можете обойтись без них.
Если все разные политики итерации итерируют в обычном порядке по подмножеству элементов, тогда посмотрите на boost::filter_iterator
.
Возможно, я бы получил несколько случаев, когда it1==it2
, но ++it1!=++it2
.Я не уверен, разрешено ли это STL.
Если я правильно понимаю, вы получили it1
, начиная с thing.normal_begin()
, и it2
, начиная с thing.other_policy_begin()
,Стандартные контейнеры не определяют результат сравнения итераторов одного и того же типа, которые принадлежат разным диапазонам, поэтому, если вы действительно использовали общий тип, то я думаю, что это будет хорошо, если документация прояснит, что, хотя operator==
делаетЕсли все получится, диапазоны будут разными в зависимости от того, откуда пришел итератор.
Например, у вас может быть skip_iterator
, который принимает в качестве параметра конструктора количество шагов, которые он должен продвигать каждый раз ++
называется.Затем вы можете либо включить это целое число в сравнение, чтобы thing.skip_begin(1) != thing.skip_begin(2)
, либо исключить его, чтобы thing.skip_begin(1) == thing.skip_begin(2)
но ++(++(thing.skip_begin(1))) == ++(thing.skip_begin(2))
.Я думаю, что либо хорошо, если это задокументировано, либо вы можете задокументировать, что сравнивать их - UB, если они не исходили из одной и той же начальной точки.