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_traitsand tag dispatch:Note that
iterator_categoryis a type (one ofstd::input_iterator_tagetc.), soiterator_category()is not a function call; it's an expression that constructs a temporary prvalue of that type. The appropriate overload ofadvance_implis then selected by normal overload resolution. This is called tag dispatch. Equivalently one could write:The overloads of
advance_implare receiving as their third argument an unnamed argument that is an instance of their chosen tag type.