
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):
http://lists.boost.org/Archives/boost/2010/03/163039.php
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 "boost/iterator/detail/facade_iterator_category.hpp".
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".
Regards, Thomas
Without being an expert, a quick review of http://www.boost.org/doc/libs/1_42_0/libs/iterator/doc/iterator_facade.html#... 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. - Jeff