What we know about std::advance
is the following:
template <class InputIterator, class Distance>
void advance (InputIterator& i, Distance n);
Purpose
Advances the iterator i
by n
elements.
If i
is a Random Access Iterator, the function uses once operator+
or operator-
, otherwise, the function uses repeatedly the increase or decrease operator (operator++
or operator--
) until n
elements have been advanced.
My question is the following:
How is std::advance
implemented such that it recognizes if it
is a Random Access Iterator or not? How does it know it can use operator+
instead of operator++
?
Through
iterator_traits
and tag dispatch:Note that
iterator_category
is a type (one ofstd::input_iterator_tag
etc.), soiterator_category()
is not a function call; it's an expression that constructs a temporary prvalue of that type. The appropriate overload ofadvance_impl
is then selected by normal overload resolution. This is called tag dispatch. Equivalently one could write:The overloads of
advance_impl
are receiving as their third argument an unnamed argument that is an instance of their chosen tag type.