[Boost-bugs] [Boost C++ Libraries] #4488: iterator_facade operator[] return type does not function correctly

Subject: [Boost-bugs] [Boost C++ Libraries] #4488: iterator_facade operator[] return type does not function correctly
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-07-29 15:06:17


#4488: iterator_facade operator[] return type does not function correctly
-------------------------------------------------------------------------------+
 Reporter: justus.c79@… | Owner: dave
     Type: Bugs | Status: new
Milestone: Boost 1.44.0 | Component: iterator
  Version: Boost 1.44.0 | Severity: Problem
 Keywords: iterator_facade, operator_brackets_proxy, operator[], operator [] |
-------------------------------------------------------------------------------+
 iterator_facade::operator[] does not function correctly when
 iterator_facade::reference is a reference to a class or structor and you
 try to access member variables or functions via the returned reference. In
 the following example program iterator_facade::reference is std::pair<int,
 int>& and we try to access std::pair<int,int>::first via the
 iterator_facade::operator[].
 {{{
 #!C++
 #include <iostream>
 #include <boost/iterator/iterator_facade.hpp>

 template <typename T>
 class IterTest : public boost::iterator_facade<IterTest<T>, T,
     std::random_access_iterator_tag>
 {
 private:
   // base class typedef
   typedef boost::iterator_facade<IterTest<T>, T,
     std::random_access_iterator_tag, T&> iterator_facade_;

 public:
   // Standard iterator typedefs
   typedef typename iterator_facade_::value_type value_type;
   typedef typename iterator_facade_::reference reference;
   typedef typename iterator_facade_::pointer pointer;
   typedef typename iterator_facade_::iterator_category iterator_category;
   typedef typename iterator_facade_::difference_type difference_type;

   // Constructors
   IterTest() : p_(NULL) { }

   explicit IterTest(T* p) : p_(p) { }

 private:
   // Core operations for iterator_facade
   template <typename U>
   bool equal(const IterTest<U>& other) const
   { return p_ == other.p_; }

   void increment() { ++p_; }

   void decrement() { --p_; }

   reference dereference() const { return *p_; }

   void advance(difference_type n) { p_ += n; }

   template <typename U>
   difference_type distance_to(const IterTest<U>& other) const
   { return (other.p_ - p_); }

   // class friend
   template <typename>
   friend class IterTest;
   friend class boost::iterator_core_access;

   // iterator
   T* p_;
 };

 int main() {
   std::pair<int, int>* p = new std::pair<int, int>(1,2);
   std::cout << p[0].first << std::endl; // Ok for pointers

   std::vector<std::pair<int,int> > v(1, std::pair<int,int>(1,2));
   std::vector<std::pair<int,int> >::iterator vit = v.begin();
   std::cout << vit[0].first << std::endl; // Ok for std::vector::iterator

   IterTest<std::pair<int, int> > it(p);
   std::cout << it[0].first << std::endl; // error:
   // 'class boost::detail::operator_brackets_proxy<IterTest<std::pair<int,
 int> > >'
   // has no member named 'first'

   delete p;
   return 0;
 }
 }}}

 Note: Similar, code using pointer and std::vector::iterator works as
 expected.

 If we change:
 {{{
 #!C++
 std::cout << it[0].first << std::endl;
 }}}

 to:
 {{{
 #!C++
 std::cout << static_cast<std::pair<int,int>&>(it[0]).first << std::endl;
 }}}

 then the program works correctly. Obviously this is not a desireable
 solution since we want the these iterators to work in the same way as
 pointers and other standard library iterators.

 I tested the above code with Apple GCC 4.0.1, Apple GCC 4.2.1, GCC 4.4.4,
 GCC 4.5.0, Intel 11.1, and clang 1.1 release 27 compilers; all of them
 give similar error messages.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/4488>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:04 UTC