Boost logo

Boost :

Subject: Re: [boost] Bug reports - Showstoppers and Regressions
From: Stephan T. Lavavej (stl_at_[hidden])
Date: 2012-01-18 20:18:41

[Ronald Garcia]
> So my question is: if I have an iterator that satisfies the expression requirements of InputIterator
> and OutputIterator,is there *any* wording in the C++ Standard that dictates what is legally the proper
> thing to do with its iterator_category? If so, where can I find it? If it should have input_iterator_tag,
> then there is a (quite reasonable) bug in VC++ 2010's debug mode. If it should have both, then I have a
> fix for multi_array. If there is no clear answer, then the standard is underspecified (and I'm happy to
> make multi_array play well with VC++).

1. Are multi_array iterators just mutable forward iterators? If so, they should be described with forward_iterator_tag.

C++11 24.4.3 [std.iterator.tags]/1 says: "It is often desirable for a function template specialization to find out what is the most specific category of its iterator argument, so that the function can select the most efficient algorithm at compile time. To facilitate this, the library introduces category tag classes which are used as compile time tags for algorithm selection. They are: input_iterator_tag, output_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag and random_access_iterator_tag. 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."

2. I previously believed that VC was conformant here. Now I see that C++03 24.3.3 [lib.std.iterator.tags]/1 and C++11 24.4.3 [std.iterator.tags]/1 specify:

struct forward_iterator_tag : public input_iterator_tag { };

But VC has:

struct forward_iterator_tag : public input_iterator_tag, output_iterator_tag { };

We overloaded our internal _Copy_impl() on (input_iterator_tag, output_iterator_tag) and (random_access_iterator_tag, random_access_iterator_tag) to detect when the source and destination are both random-access (if so, we can ask more specific questions, like are they raw pointers to nearly-identical scalars). If the destination is actually bidirectional_iterator_tag or forward_iterator_tag, this overloading relies on those tags being convertible to output_iterator_tag, which is true for our implementation but not true according to the Standard.

I'll see about fixing this (it's probably too late for VC11, though). However, I don't believe it affects you - C++11 24.4.3 [std.iterator.tags]/1 says "the most specific category tag", so you need to choose one of the 5 tags, and something described with only input_iterator_tag can't be the destination of a copy(). Any of the other 4 tags will make both the Standard and VC happy (even though VC will be happy for two nonconformant reasons canceling each other out).

Stephan T. Lavavej
Visual C++ Libraries Developer

Boost list run by bdawes at, gregod at, cpdaniel at, john at