24 Iterators library [iterators]

24.4 Iterator primitives [iterator.primitives]

24.4.2 Standard iterator tags [std.iterator.tags]

It is often desirable for a function template specialization to find out what is the most specific category of its iterator argument, so that the function can select the most efficient algorithm at compile time.
To facilitate this, the library introduces category tag classes which are used as compile time tags for algorithm selection.
They are: output_iterator_tag, input_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, random_access_iterator_tag, and contiguous_iterator_tag.
For every iterator of type I, iterator_traits<I>​::​iterator_category shall be defined to be a category tag that describes the iterator's behavior.
Additionally, iterator_traits<I>​::​iterator_concept may be used to indicate conformance to the iterator concepts ([iterator.concepts]).
namespace std { struct output_iterator_tag { }; struct input_iterator_tag { }; struct forward_iterator_tag: public input_iterator_tag { }; struct bidirectional_iterator_tag: public forward_iterator_tag { }; struct random_access_iterator_tag: public bidirectional_iterator_tag { }; struct contiguous_iterator_tag: public random_access_iterator_tag { }; }
[Example 1: 
A program-defined iterator BinaryTreeIterator can be included into the bidirectional iterator category by specializing the iterator_traits template: template<class T> struct iterator_traits<BinaryTreeIterator<T>> { using iterator_category = bidirectional_iterator_tag; using difference_type = ptrdiff_t; using value_type = T; using pointer = T*; using reference = T&; };
— end example]
[Example 2: 
If evolve() is well-defined for bidirectional iterators, but can be implemented more efficiently for random access iterators, then the implementation is as follows: template<class BidirectionalIterator> inline void evolve(BidirectionalIterator first, BidirectionalIterator last) { evolve(first, last, typename iterator_traits<BidirectionalIterator>::iterator_category()); } template<class BidirectionalIterator> void evolve(BidirectionalIterator first, BidirectionalIterator last, bidirectional_iterator_tag) { // more generic, but less efficient algorithm } template<class RandomAccessIterator> void evolve(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag) { // more efficient, but less generic algorithm }
— end example]