Как сообщить функции advance() использовать оператор + = на входных итераторах, если они не являются произвольным доступом
Рассмотрим входной итератор, например join_iterator
: он выполняет итерацию по конкатенации других диапазонов. Повторный вызов ++i
может быть намного медленнее, чем простой i += n
.
Тем не менее, большинство С++-кодов, которые требуют продвижения итератора произвольной суммой, использует std::advance
, который автоматически прибегает к вызову ++i
, когда итератор не является произвольным доступом.
(К сожалению, большинство людей используют std::advance(i, n)
вместо using std::advance; advance(i, n)
, поэтому я не могу просто поставить advance
для моего итератора и полагаться на ADL.)
С другой стороны, я не могу использовать +
или +=
, потому что итераторы ввода не должны их реализовывать.
Итак, вопрос: как я могу поддержать такой сценарий, когда:
-
Реализация такого итератора?
-
Используя итератор ввода, который может иметь оптимизированный operator +=
?
(Обратите внимание, что advance
и +
не единственный сценарий, в котором это имеет значение - distance
и -
, имеет ту же проблему.)
Ответы
Ответ 1
Согласно С++ 11 §24.4.4,
Поскольку только итераторы произвольного доступа предоставляют операторы + и -, библиотека предоставляет два шаблона функций advance
и distance
. Эти шаблоны функций используют +
и -
для итераторов произвольного доступа (и, следовательно, для них постоянное время); для ввода, форвардных и двунаправленных итераторов, которые они используют ++ для обеспечения линейных временных реализаций.
Вам нужно только определить +
и -
и указать std::random_access_iterator_tag
. Нет необходимости специализироваться или перегружать std::advance
.