Boost logo

Boost :

Subject: Re: [boost] Bug reports - Showstoppers and Regressions
From: Julian Gonggrijp (j.gonggrijp_at_[hidden])
Date: 2012-01-24 07:24:00


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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk