$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-users] [range] joining ranges with different value types, then transforming with a polymorphic functor
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2011-02-25 19:17:43
Hello,
 
I would like to do the following with Boost.Range:
 
#include <vector>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/join.hpp>
#include <boost/foreach.hpp>
 
using boost::adaptors::transformed;
using boost::join;
 
struct A { int x; };
struct B { int x; };
struct C { int x; };
 
struct to_C
{
    C operator()(A a) const { return C{a.x}; }
    C operator()(B b) const { return C{b.x}; }
};
 
int main()
{
    std::vector<A> a;
    std::vector<B> b;
    BOOST_FOREACH(const C& c, join(a, b) | transformed(to_C()))
    {
        // do something
    }
    return 0;
}
Basically, I am joining two ranges with different value types (A and B), then transforming the resulting range with a polymorphic functor (to_C) that converts either of A or B to a common third type, C.
 
When I try to loop through this resulting range, however, I get the following compiler errors:
 
In file included from ../../lib/boost/boost/range/join.hpp:15:0,
from test.cpp:3:
../../lib/boost/boost/range/detail/join_iterator.hpp: In member function 'A &
    boost::range_detail::join_iterator_union<
        vector<A>::iterator, vector<B>::iterator, A &
    >::dereference(unsigned int) const':
../../lib/boost/boost/range/detail/join_iterator.hpp:216:42:   instantiated
    from 'boost::range_detail::join_iterator<
        vector<A>::iterator, vector<B>::iterator, A, A &
      , boost::random_access_traversal_tag
    >::A & boost::range_detail::join_iterator<
        vector<A>::iterator, vector<B>::iterator, A, A &
      , boost::random_access_traversal_tag
    >::dereference() const'
../../lib/boost/boost/iterator/iterator_facade.hpp:517:32:   instantiated from
    'static boost::range_detail::join_iterator<
        vector<A>::iterator, vector<B>::iterator, A, A &
      , boost::random_access_traversal_tag
    >::A & boost::iterator_core_access::dereference(
        const boost::range_detail::join_iterator<
            vector<A>::iterator, vector<B>::iterator, A, A &
          , boost::random_access_traversal_tag
        > &
    )'
../../lib/boost/boost/iterator/iterator_facade.hpp:643:67:   instantiated from
    'boost::iterator_facade<I, V, TC, R, D>::A & boost::iterator_facade<
        I, V, TC, R, D
    >::operator *() const'
../../lib/boost/boost/iterator/transform_iterator.hpp:121:31:   instantiated
    from 'boost::detail::transform_iterator_base<
        to_C
      , boost::range_detail::join_iterator<
            vector<A>::iterator, vector<B>::iterator, A, A &
          , boost::random_access_traversal_tag
        >, boost::use_default, boost::use_default
    >::type::C boost::transform_iterator<
        UnaryFunction
      , boost::range_detail::join_iterator<
            vector<A>::iterator, vector<B>::iterator, A, A &
          , boost::random_access_traversal_tag
        >, boost::use_default, boost::use_default
    >::dereference() const'
../../lib/boost/boost/iterator/iterator_facade.hpp:517:32:   instantiated from
    'static boost::transform_iterator<
        to_C
      , boost::range_detail::join_iterator<
            vector<A>::iterator, vector<B>::iterator, A, A &
          , boost::random_access_traversal_tag
        >, boost::use_default, boost::use_default
    >::C boost::iterator_core_access::dereference(
        const boost::transform_iterator<
            to_C
          , boost::range_detail::join_iterator<
                vector<A>::iterator, vector<B>::iterator, A, A &
              , boost::random_access_traversal_tag
            >, boost::use_default, boost::use_default
        > &
    )'
../../lib/boost/boost/iterator/iterator_facade.hpp:643:67:   instantiated from
    'boost::iterator_facade<
        I, V, TC, R, D
    >::C boost::iterator_facade<I, V, TC, R, D>::operator *() const'
../../lib/boost/boost/foreach.hpp:748:58:   instantiated from 'boost
    ::foreach_detail_::foreach_reference<
        boost::range_detail::transformed_range<
            to_C, const boost::joined_range<vector<A>, vector<B> >
        >, mpl_::bool_<true>
    >::ame boost::foreach_detail_::foreach_reference<T, C>::type = C boost
    ::foreach_detail_::deref(
        boost::foreach_detail_::const boost::foreach_detail_::auto_any_base &
      , boost::foreach_detail_::type2type<
            boost::range_detail::transformed_range<
                to_C, const boost::joined_range<vector<A>, vector<B> >
            >, mpl_::bool_<true>
        > *
    )'
test.cpp:23:5:   instantiated from here
../../lib/boost/boost/range/detail/join_iterator.hpp:71:37: error: no match for
    ternary 'operator?:' in '(selected != 0u) ? this->boost::range_detail
    ::join_iterator_union<vector<A>::iterator, vector<B>::iterator, A &>
    ::m_it2.vector<A>::iterator::operator *() : this->boost::range_detail
    ::join_iterator_union<vector<A>::iterator, vector<B>::iterator, A &>
    ::m_it1.vector<A>::iterator::operator *()'
 
Is there a way to do this?
 
Thanks,
Nate.