
Ronald Garcia wrote:
Listed under showstoppers is ticket 4874 for multi_array. To address this tag I need a language lawyer, and I am not one.
The issue is that VC 2010 under debug mode fails to compile multi_array because it's copy() function checks iterator tags. multi_array iterators have had input_iterator_tag but not output_iterator tag.
I'm not a language lawyer either (far from it) and I have never used multi_array. I did however read all of the SGI STL manual, so perhaps I can still help.
The outstanding question I have is whether it is necessary or even legal for an iterator to have an iterator_category that is somehow both input_iterator_tag AND output_iterator tag simultaneously.
First I say *legal* because in my copy of a standard draft, (24.3.3) says: For every iterator of type Iterator, iterator_traits<Iterator>::iterator_category shall be defined to be the most specific category tag that describes the iterator’s behavior.
Your iterator models Input Iterator. Since it's used to iterate over a container, I assume that the same iterator can be used to pass over its range multiple times. That would mean it's also a Forward Iterator. According to the manual, Forward Iterator is a refinement of both Input Iterator and Output Iterator: http://www.sgi.com/tech/stl/ForwardIterator.html So it looks like the most specific tag for your iterator class is at least forward_iterator_tag.
I'm unclear on whether that can be any tag other than the specific ones listed. In particular, can I inherit two tags to merge them.
You probably could, but I don't think it would be a good idea in this case. For one, there already appears to be a unique most specific iterator tag for your iterator class which sort-of incorporates output_iterator. More importantly, if you explicitly use output_iterator as a category, you'll remove the possibility for your iterator class to be a const iterator...
Second, I say *necessary* because while input_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag, and random_access_iterator_tag form an inheritance chain, none of them inherit from output_iterator_tag. Furthermore, const_iterators like "const int *" are not OutputIterators but seem to still be RandomAccessIterators. So in this case I'm not sure when (if ever) it is necessary to have an iterator category that is convertible to output_iterator_tag. In fact, the Boost.Concept library doesn't ever even look at the iterator_category when checking OutputIterator concept. All uses of output_iterator_tag I can find in the standard are things like back_inserter and front_inserter,
... as you explained here! A mutable Forward Iterator is also an Output Iterator, but a const Forward Iterator is not. So the only correct application for output_iterator_tag is in iterator classes whose primary purpose is to store values, such as back_insert_iterator and ostream_iterator. For those classes it simply wouldn't make sense to be a const iterator.
things that are not "really" iterators, so to speak.
By a "real" iterator you probably mean an iterator which can pass over its range multiple times. This again reveals that you're probably at least talking about a Forward Iterator. Rule of thumb: Sequence containers are always at least Forward Iterable. Rule of thumb: if you feel tempted to use both input_iterator_tag and output_iterator_tag, you should probably use forward_iterator_tag instead. My advice: use forward_iterator_tag and see whether that works better with MSVC. HTH, Julian