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 = typename Iterator::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);
}
bool equal(Enumerator const& other) const
{
return mPos == mPos;
}
void increment()
{
mCount += mStep;
mPos += 1;
}
void decrement()
{
mCount -= mStep;
mPos -= 1;
}
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
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
G++:
In file included from /usr/include/boost/iterator/iterator_adaptor.hpp:15:0,
from Enumerate.h:18,
from Enumerate.cpp:1:
/usr/include/boost/iterator/iterator_facade.hpp: In static member function 'static boost::detail::operator_arrow_result::type boost::detail::operator_arrow_result::make(Reference) [with ValueType = Iterator::Enumerated, Reference = Iterator::Enumerated, Pointer = Iterator::Enumerated*, boost::detail::operator_arrow_result::type = boost::detail::operator_arrow_proxy >]':
/usr/include/boost/iterator/iterator_facade.hpp:648:49: instantiated from 'boost::iterator_facade::pointer boost::iterator_facade::operator->() const [with Derived = Iterator::Enumerator<__gnu_cxx::__normal_iterator, int>, Value = Iterator::Enumerated, CategoryOrTraversal = boost::random_access_traversal_tag, Reference = Iterator::Enumerated, Difference = int, boost::iterator_facade::pointer = boost::detail::operator_arrow_proxy >]'
Enumerate.cpp:27:14: instantiated from here
/usr/include/boost/iterator/iterator_facade.hpp:327:49: error: no matching function for call to 'implicit_cast(Iterator::Enumerated*)'
Any help would be greatly appreciated,
Bets regards,
Jens