How does one define forward-output-iterators in C++11 in a canonical way?
According to the standard a forward_iterator is only a input_iterator. So the corresponding forward_iterator_tag
only extends input_iterator_tag
. If we are using std::iterator
to define our iterators, what tag do we use for a forward-output-iterator?
Is it canonical to define a private tag that extends both forward_iterator_tag
and output_iterator_tag
or is there a better solution?
Forward iterators are used to read the contents from the beginning to the end of a container. Forward iterator use only increments operator (++) to move through all the elements of a container. Therefore, we can say that the forward iterator can only move forward. A Forward iterator is a multi-pass iterator.
A Forward Iterator is an iterator that corresponds to the usual intuitive notion of a linear sequence of values. It is possible to use Forward Iterators (unlike Input Iterators and Output Iterators) in multipass algorithms.
Bidirectional iterators are the iterators used to access the elements in both the directions, i.e., towards the end and towards the beginning. A random access iterator is also a valid bidirectional iterator. Many containers implement the bidirectional iterator such as list, set, multiset, map, multimap.
An Output Iterator is a type that provides a mechanism for storing (but not necessarily accessing) a sequence of values.
The canonical thing to do is to inherit from std::iterator<std::forward_iterator_tag, T>
only. Iterators have only one category.
The standard has no algorithms (or other uses) for an output iterator that is also a forward iterator. All uses of output iterators in the standard require only single-pass.
Instead, the standard has the idea of mutable vs. immutable iterators of categories forward/bidi/randomaccess. All the algorithms that need to write through iterators, and that require better than single-pass, also read through the same iterators they write through. This is std::remove
, std::sort
and other mutating algorithms.
The difference between mutable and immutable iterators is not detected by iterator tag, it's determined by whether the assignment expressions are well-formed. So for example if you pass an iterator to std::sort
that's immutable, then the algorithm won't compile anyway, so there's generally no need for an input iterator to also be tagged with output_iterator_tag
. All algorithms that require an OutputIterator
will Just Work with a mutable ForwardIterator
, again there is no need for it to be tagged with output_iterator_tag
.
If you have different needs from those of the standard algorithms then I can't immediately think of a reason that your proposal won't work for your iterators. But it won't detect mutable standard iterators. For example std::deque<int>::iterator
and int*
have iterator category random_access_iterator_tag
, not your private tag and not anything to do with output_iterator_tag
. So you would probably be better off defining your own traits class rather than hoping to adapt the existing iterator_traits::iterator_category
to provide the information you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With