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.
Steve jessop
source share