Boost logo

Boost Users :

Subject: [Boost-users] [range] no matching function for call to make_begin_strided_iterator?
From: Oliver Kowalke (oliver.kowalke_at_[hidden])
Date: 2015-05-11 03:52:00


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<Rng,
Category>::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<typename
boost::range_iterator<C>::type>::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::is_convertible<std::input_iterator_tag,
boost::iterators::incrementable_traversal_tag>,
boost::mpl::identity<std::input_iterator_tag>,
boost::iterators::detail::old_category_to_traversal<std::input_iterator_tag>
>::type)’
>::type()),

Could you give me a hint what is missing?

thx,
Oliver

#include <iostream>
#include <iterator>
#include <vector>

#include <boost/range.hpp>
#include <boost/range/adaptor/strided.hpp>

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';
}



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net