Defined in header <iterator> | ||||
---|---|---|---|---|
| ||||
| ||||
| ||||
| ||||
|
Defines the category of an iterator. Each tag is an empty type and corresponds to one of the five iterator categories:
-
input_iterator_tag
corresponds toInputIterator
. -
output_iterator_tag
corresponds toOutputIterator
. -
forward_iterator_tag
corresponds toForwardIterator
. -
bidirectional_iterator_tag
corresponds toBidirectionalIterator
. -
random_access_iterator_tag
corresponds toRandomAccessIterator
.
Iterator category tags carry information that can be used to select the most efficient algorithms for the specific requirement set that is implied by the category.
For every iterator type, a typedef std::iterator_traits<Iterator>::iterator_category
is available, which is an alias to one of these five tag types.
NotesThere is no separate tag for | (since C++17) |
Example
Common technique for algorithm selection based on iterator category tags is to use a dispatcher function (the alternative is std::enable_if
).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <iostream> #include <vector> #include <list> #include <iterator> template < class BDIter > void alg(BDIter, BDIter, std::bidirectional_iterator_tag) { std::cout << "alg() called for bidirectional iterator\n" ; } template < class RAIter> void alg(RAIter, RAIter, std::random_access_iterator_tag) { std::cout << "alg() called for random-access iterator\n" ; } template < class Iter > void alg(Iter first, Iter last) { alg(first, last, typename std::iterator_traits<Iter>::iterator_category()); } int main() { std::vector< int > v; alg(v.begin(), v.end()); std::list< int > l; alg(l.begin(), l.end()); // std::istreambuf_iterator<char> i1(std::cin), i2; // alg(i1, i2); // compile error: no matching function for call } |
Output:
1 2 | alg() called for random-access iterator alg() called for bidirectional iterator |
Example
Algorithm selection based on iterator category tags using std::enable_if
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include <iostream> #include <vector> #include <list> #include <iterator> template < typename Condition, typename T = void > using EnableIf_t = typename std::enable_if<Condition::value, T>::type; template < typename Iterator, typename IteratorTag> using IsSameIteratorCond = std::is_same<IteratorTag, typename std::iterator_traits<Iterator>::iterator_category>; template < typename BDIter, typename = EnableIf_t<IsSameIteratorCond<BDIter, std::bidirectional_iterator_tag>>> void alg(BDIter, BDIter) { std::cout << "alg() called for bidirectional iterator\n" ; } template < typename RAIter, typename = EnableIf_t<IsSameIteratorCond<RAIter, std::random_access_iterator_tag>>, typename = void > // dummy value to avoid template re-definition error void alg(RAIter, RAIter) { std::cout << "alg() called for random-access iterator\n" ; } int main() { std::vector< int > v; alg(v.begin(), v.end()); std::list< int > l; alg(l.begin(), l.end()); } |
Output:
1 2 | alg() called for random-access iterator alg() called for bidirectional iterator |
See also
the basic iterator (class template) | |
provides uniform interface to the properties of an iterator (class template) |
Please login to continue.