The canonical method for determining an iterator with direct output

How to define frames using direct output iterators in C ++ 11?

According to the standard forward_iterator is only input_iterator. Thus, the corresponding forward_iterator_tag applies only to input_iterator_tag . If we use std::iterator to define our iterators, what tag do we use for 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?

+7
source share
1 answer

The canonical task is to inherit only from std::iterator<std::forward_iterator_tag, T> . Iterators have only one category.

The standard does not have algorithms (or other uses) for the output iterator, which is also a transfer iterator. All use of output iterators in the standard requires only a single pass.

Instead, the standard has the idea of ​​mutable vs. immutable iterators of categories forward / bidi / randomaccess. All algorithms that need to be written via iterators, and which require better than single-pass, also read the same iterators that they write. These are std::remove , std::sort and other mutating algorithms.

The difference between mutable and immutable iterators is not determined by the iterator tag, it is determined whether the assignment expressions are formed correctly. So, for example, if you pass the iterator to std::sort immutable, then the algorithm will not compile in any case, therefore, in general, there is no need for the input iterator to be marked output_iterator_tag . All algorithms that require an OutputIterator will simply work with a variable ForwardIterator , again there is no need to mark it with output_iterator_tag tags.

If you have different needs from standard algorithms, I cannot immediately recall the reason why your proposal will not work for your iterators. But it will not detect mutable standard iterators. For example, std::deque<int>::iterator and int* have the random_access_iterator_tag iterator category and not your private tag and have nothing to do with output_iterator_tag . This way, you will probably be better off defining your own feature class, rather than hoping to adapt the existing iterator_traits::iterator_category to provide the required information.

+6
source

All Articles