Subject: Re: [boost] [iterator] Help needed understanding output_iterator requirements
From: Jeffrey Hellrung (jhellrung_at_[hidden])
Date: 2010-03-15 11:12:30
Thomas Klimpel wrote:
> Dear iterator experts,
> Jesse Perla recently reported that boost::multi_array fails compilation for many basic tasks on MSVC 2010. I investigated the failures, because I had already investigated other failures on MSVC 2010 reported by Jesse Perla for boost::ublas. While I'm quite familiar with boost::ublas, I'm a complete novice with respect to boost::multi_array and boost::iterator.
> I could track the failures to a specific (intentional?) behavior of iterator_facade from Boost.Iterator (more specifically of facade_iterator_category.hpp):
> Thomas Klimpel wrote:
>> What effectively happens it that the iterator gets the category
>> "input_iterator", but std::copy wants to have an "output_iterator". I
>> think I understand why the iterator doesn't satisfies the requirement
>> of a "forward_iterator", but it's unclear to me why it didn't qualify
>> as an "output_iterator". There is an "input_output_iterator_tag" in
>> "boost/iterator/detail/facade_iterator_category.hpp", so it would have
>> been possible for the iterator to be both "input_iterator" and
>> "output_iterator". However, it seems to me that
>> "input_output_iterator_tag" is never used in the Boost.Iterator
>> library. I would have to read more about "output_iterator" to
>> understand whether Boost.Iterator is correct here. With my current
>> understanding of "output_iterator", I would say it's a bug in
>> Perhaps somebody with more knowledge about "output_iterator" and
>> Boost.Iterator can explain to me why an iterator using the
>> "boost::random_access_traversal_tag" for the "CategoryOrTraversal"
>> template parameter of "iterator_facade" will never get the category
>> "output_iterator" (or "input_output_iterator_tag").
> Of course I could go on and read more about "output_iterator", or find out whether the Boost.Iterator documentation has to say something about this issue, but since I only came to this problem because I wanted to help Jesse Perla on a problem with boost::multi_array, I would much prefer if an "iterator expert" could "take over".
Without being an expert, a quick review of
shows that std::output_iterator_tag is never chosen as the iterator
category by boost::iterator_facade. It also shows that the behavior of
choosing std::input_iterator_tag for your particular case is the
documented behavior. Of course, this doesn't shed any light on the
motivation behind this decision. It may have been the intention that
output iterators should be explicitly declared as such by specifying the
category as std::output_iterator_tag.
This aspect of the standard that treats iterators with proxy references
as automatically have the very lowest of traversal categories is
annoying at best. I've resorted to overriding the traversal category
normally deduced by boost::iterator_facade; I haven't had any ill
effects yet, but I'm not sure *technically* what parts of the standard
(and *practically*, in terms of the various implementations on the
various compilers) depends on, e.g., dereferenced random-access
iterators returning lvalue references.