On Tue, Apr 17, 2012 at 5:03 AM, Jens Auer <jensa@miltenyibiotec.de> wrote:

Hi,

 

I am implementing something similar to python’s enumerate using boost iterator adapter, but I am running into two problems I am unable to solve. Both problems use my Enumerate-adaptor defined as:

#include <utility>

 

#include <boost/iterator/iterator_adaptor.hpp>

 

namespace Iterator

{

// some simple wrapper to have better names than std::pair

template<typename T, typename X>

struct Enumerated

{

   Enumerated(T i, X x):

      count(i),

      value(x)

   {

 

   }

 

   T count;

   X value;

};

 

template< typename Iterator, typename T = typename Iterator::difference_type>

class Enumerator:

   public boost::iterator_adaptor<Enumerator<Iterator, T>,

                                  Iterator,

                                  Enumerated<T, typename Iterator::value_type>,

                                  boost::use_default,

                                  Enumerated<T, typename Iterator::reference> >

{

public:

   Enumerator():

      mCount(),

      mPos(),

      mStep()

   {

 

   }

 

   template<typename It>

   explicit Enumerator(It i, T start=T(), T step=T(1) ):

      mCount(start),

      mPos(i),

      mStep(step)

   {

 

   }

 

private:

   friend class boost::iterator_core_access;

 

   Enumerated<T, typename Iterator::reference >  dereference() const

   {

      return Enumerated<T, typename Iterator::reference >(mCount, *mPos);

   }

 

   Enumerated<T, typename Iterator::reference >  dereference()

   {

      return Enumerated<T, typename Iterator::reference >(mCount, mPos);

   }


Pretty sure this latter overload of dereference will never get called, and it wouldn't compile anyway ("mPos" should be "*mPos").

 

   bool equal(Enumerator<Iterator, T> const& other) const

   {

      return mPos == mPos;

   }


Error already noted here.
 

 

   void increment()

   {

      mCount += mStep;

      mPos += 1;

   }


Consider ++mPos?
 

 

   void decrement()

   {

      mCount -= mStep;

      mPos -= 1;

   }


Similarly, consider --mPos?
 

 

   void advance(typename Iterator::difference_type step)

   {

      mCount += step * mStep;

      mPos += step;

   }

 

   typename Iterator::difference_type distance_to(Enumerator<Iterator, T> const& other) const

   {

      return std::distance(mPos, other.mPos);

   }

 

   T mCount;

   Iterator mPos;

   typename Iterator::difference_type mStep;

};

 

template<typename Iterator, typename T>

Enumerator<Iterator, T> enumerate(Iterator i, T start=0, T step=1)

{

   return Enumerator<Iterator, T>(i, start, step);

}

 

When I compile the following sample program, msvc (VS2010) prints an error, but g++ does not have any problems.

#include <vector>

#include <iostream>

#include <algorithm>

 

void foo()

{

   std::vector<int> v;

 

   auto i = Iterator::enumerate(v.begin(), 0, 1);

   auto j = Iterator::enumerate(v.end(), 0, 1);

 

   std::for_each( i, j, [](decltype(*i) e)

   {

      std::cout << e.count << ", " << e.value << std::endl;

   });

}

Error      1             error C2665: 'std::_Debug_range2' : none of the 2 overloads could convert all the argument types                d:\programme\microsoft visual studio 10.0\vc\include\xutility                728


Can you give more context to the error message?
 

My second problem can be reproduced with the following sample program on both msvc and g++:

 

#include <vector>

#include <iostream>

#include <algorithm>

 

void foo()

{

   std::vector<int> v;

 

   auto i = Iterator::enumerate(v.begin(), 0, 1);

 

   auto y = i->count;

   auto z = i->value;

}

MSVC:

Error      3             error C2664: 'boost::implicit_cast' : cannot convert parameter 1 from 'Iterator::Enumerated<T,X> *' to 'boost::detail::operator_arrow_proxy<T>'         c:\software development\externals\include\boost\iterator\iterator_facade.hpp  326


As Mateusz has noted, I believe you're running into

https://svn.boost.org/trac/boost/ticket/5697

which was just recently fixed in trunk. See if that resolves your problem.

[snip compiler trace]

- Jeff