
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 = typenameIterator::difference_type>
****
class Enumerator:****
public boost::iterator_adaptor<Enumerator<Iterator, T>,****
Iterator,****
Enumerated<T, typenameIterator::value_type>, ****
boost::use_default,****
Enumerated<T, typenameIterator::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