On Tue, Apr 17, 2012 at 5:03 AM, Jens Auer
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
**** ** **
namespace Iterator****
{****
// some simple wrapper to have better names than std::pair****
template
**** 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
,**** Iterator,****
Enumerated
, **** boost::use_default,****
Enumerated
> **** {****
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
dereference() const**** {****
return Enumerated
(mCount, *mPos);* *** }****
** **
Enumerated
dereference()**** {****
return Enumerated
(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
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
const& other) const**** {****
return std::distance(mPos, other.mPos);****
}****
** **
T mCount;****
Iterator mPos;****
typename Iterator::difference_type mStep;****
};****
** **
template
**** Enumerator
enumerate(Iterator i, T start=0, T step=1)**** {****
return Enumerator
(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
*' 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