Hi,
if the test app below does not use adaptor strided in the for-range loop it
works.
If the adaptors is used the app fails with:
../../../../../boost/range/adaptor/strided.hpp: In instantiation of
‘boost::range_detail::strided_range::strided_range(Difference, Rng&) [with Difference = int; Rng =
foo::X<int>; Category = boost::iterators::single_pass_traversal_tag]’:
../../../../../boost/range/adaptor/strided.hpp:656:54: required from
‘boost::range_detail::strided_range<Rng>
boost::range_detail::operator|(Rng&, const
boost::range_detail::strided_holder<Difference>&) [with Rng = foo::X<int>;
Difference = int; typename
boost::iterators::pure_iterator_traversal::type =
boost::iterators::single_pass_traversal_tag]’
fibonacci.cpp:188:50: required from here
../../../../../boost/range/adaptor/strided.hpp:631:34: error: no matching
function for call to ‘make_begin_strided_iterator(foo::X<int>&, int&,
boost::mpl::eval_if,
boost::mpl::identitystd::input_iterator_tag,
boost::iterators::detail::old_category_to_traversalstd::input_iterator_tag
::type)’
>::type()),
Could you give me a hint what is missing?
thx,
Oliver
#include <iostream>
#include <iterator>
#include <vector>
#include
#include
namespace foo {
template< typename T >
class X {
private:
typedef std::vector< T > vec_t;
vec_t vec_;
public:
X( vec_t const& vec) :
vec_( vec) {
}
class iterator : public std::iterator< std::input_iterator_tag, T >
{
private:
X * x_;
typename vec_t::iterator i_;
public:
typedef typename iterator::pointer pointer_t;
typedef typename iterator::reference reference_t;
iterator() :
x_( 0), i_()
{}
explicit iterator( X * x) :
x_( x), i_( x_->vec_.begin() )
{}
iterator( iterator const& other) :
x_( other.x_), i_( other.i_)
{}
iterator & operator=( iterator const& other) {
if ( this == & other) return * this;
x_ = other.x_;
i_ = other.i_;
return * this;
}
bool operator==( iterator const& other) const
{ return other.x_ == x_ && other.i_ == i_; }
bool operator!=( iterator const& other) const
{ return other.x_ != x_ || other.i_ != i_; }
iterator & operator++() {
++i_;
return * this;
}
iterator operator++( int) {
i_++;
return * this;
}
reference_t operator*() const
{ return * i_; }
pointer_t operator->() const
{ return & ( * i_); }
};
class const_iterator : public std::iterator< std::input_iterator_tag,
const T >
{
private:
X * x_;
typename vec_t::const_iterator i_;
public:
typedef typename iterator::pointer pointer_t;
typedef typename iterator::reference reference_t;
const_iterator() :
x_( 0), i_()
{}
explicit const_iterator( X * x) :
x_( x), i_( x_->vec_.begin() )
{}
const_iterator( const_iterator const& other) :
x_( other.x_), i_( other.i_)
{}
const_iterator & operator=( const_iterator const& other) {
if ( this == & other) return * this;
x_ = other.x_;
i_ = other.i_;
return * this;
}
bool operator==( const_iterator const& other) const
{ return other.x_ == x_ && other.i_ == i_; }
bool operator!=( const_iterator const& other) const
{ return other.x_ != x_ || other.i_ != i_; }
const_iterator & operator++() {
++i_;
return * this;
}
const_iterator operator++( int) {
i_++;
return * this;
}
reference_t operator*() const
{ return * i_; }
pointer_t operator->() const
{ return & ( * i_); }
};
friend class iterator;
friend class const_iterator;
};
template< typename T >
typename X< T >::iterator
range_begin( X< T > & c)
{ return typename X< T >::iterator( & c); }
template< typename T >
typename X< T >::const_iterator
range_begin( X< T > const& c)
{ return typename X< T >::const_iterator( & c); }
template< typename T >
typename X< T >::iterator
range_end( X< T > &)
{ return typename X< T >::iterator(); }
template< typename T >
typename X< T >::const_iterator
range_end( X< T > const&)
{ return typename X< T >::const_iterator(); }
template< typename T >
typename X< T >::iterator
begin( X< T > & c)
{ return boost::begin( c); }
template< typename T >
typename X< T >::const_iterator
begin( X< T > const& c)
{ return boost::begin( c); }
template< typename T >
typename X< T >::iterator
end( X< T > & c)
{ return boost::end( c); }
template< typename T >
typename X< T >::const_iterator
end( X< T > const& c)
{ return boost::end( c); }
}
namespace boost {
template< typename T >
struct range_mutable_iterator< foo::X< T > >
{ typedef typename foo::X< T >::iterator type; };
template< typename T >
struct range_const_iterator< foo::X< T > >
{ typedef typename foo::X< T >::const_iterator type; };
}
int main()
{
std::vector< int > vec = { 1,2,3,4,5,6,7,8,9,10 };
auto x = foo::X< int >( vec);
for (auto i : x | boost::adaptors::strided( 2) )
std::cout << i << " ";
std::cout << '\n';
}