Спецификация C ++ относительно того, что именно является контейнером STL, требует, чтобы у любого типа контейнера STL было несколько различных доступных полей. Некоторые из них, например begin()
и end()
, являются функциями, а другие, например iterator
, являются типами. Эти ограничения также применяются к итераторам. Это позволяет шаблонным функциям C ++ анализировать свои типы аргументов для поиска дополнительных свойств. Например, все типы итераторов STL должны определять поле iterator_category
, содержащее тип, кодирующий их возможности. Таким образом, алгоритмы STL могут иметь разные реализации разных функций в зависимости от мощности итераторов, которые они принимают. Примером класса является функция distance
, которая принимает два итератора и возвращает количество пробелов между ними. Если входное значение является просто ForwardIterator
или BidirectionalIterator
, это работает, продвигая итераторы вперед и подсчитывая, сколько шагов было сделано, которое выполняется в O (n). Если входное значение равно RandomAccessIterator
, то итераторы можно просто вычесть, чтобы получить результат в O (1).
До C ++ 17 рекомендовалось включать заголовок <iterator>
и наследовать от std::iterator
для автоматической генерации необходимых вложенных типов (reference
, pointer
и т. Д.). Этот тип теперь устарел , поэтому вам придется либо вручную добавить typedef
s, либо специализироваться std::iterator_traits
для экспорта этой информации.
Что касается операторов, которые необходимо перегрузить, как минимум вам нужно получить ++
(префикс и постфикс), ==
, !=
, *
(разыменование указателя) и ->
определено , Все типы итераторов поддерживают это. Для двунаправленных итераторов или выше вы должны также определить --
(префикс и постфикс). Наконец, для итераторов с произвольным доступом вы должны поддерживать []
, +
, +=
, -
(выполнить резервное копирование множества шагов и вычесть два итератора), -=
, <
, >
, <=
и >=
.
Надеюсь, это поможет!