2

Hi!

I'm desperately trying to nest different views using Boost Fusion. I'm still in the process of learning Fusion, so apologies if this is a silly question.

My actual scenario is much more complex, but I'll try to simplify it as much as possible for the sake of illustration. I have two Fusion vectors v1 and v2 which are themselves contained in another Fusion vector vv:

typedef fusion::vector<int, int, int> IntVector;
IntVector v1(1,2,3);
IntVector v2(4,5,6);
typedef fusion::vector<IntVector&, IntVector&> VVector;
VVector vv(v1,v2);

What I would like to achieve now is an interleaving of the vectors contained in vv, i.e. a lazy view which traverses vv in the following order:

1,4,2,5,3,6

In order to achieve that, I was thinking about nesting zip and flatten as follows:

typedef fusion::zip_view<VecVector> ZipView;
auto zv = ZipView(vv);
typedef fusion::flatten_view<ZipView> FlattenView;
auto fv = FlattenView(zv);

This compiles, however, as soon as I start dereferencing elements in fv, problems arise. For example:

auto first = fusion::begin(fv);

This produces the following output:

iteration01.cpp:486:27:   instantiated from here
boost/fusion/view/flatten_view/flatten_view_iterator.hpp:80:36: error: no matching function for call to ‘boost::fusion::detail::make_descent_cons<boost::fusion::vector_iterator<boost::fusion::vector2<int&, int&>, 0>, void>::apply(const type)’
boost/fusion/view/flatten_view/flatten_view_iterator.hpp:80:36: note: candidate is:
boost/fusion/view/flatten_view/flatten_view_iterator.hpp:54:28: note: static boost::fusion::detail::make_descent_cons<Iterator, <template-parameter-1-2> >::type boost::fusion::detail::make_descent_cons<Iterator, <template-parameter-1-2> >::apply(const Iterator&) [with Iterator = boost::fusion::vector_iterator<boost::fusion::vector2<int&, int&>, 0>, <template-parameter-1-2> = void, boost::fusion::detail::make_descent_cons<Iterator, <template-parameter-1-2> >::type = boost::fusion::cons<boost::fusion::vector_iterator<boost::fusion::vector2<int&, int&>, 0>, boost::fusion::nil_>]
boost/fusion/view/flatten_view/flatten_view_iterator.hpp:54:28: note:   no known conversion for argument 1 from ‘const type {aka const boost::fusion::vector_iterator<const boost::fusion::vector2<int&, int&>, 0>}’ to ‘const boost::fusion::vector_iterator<boost::fusion::vector2<int&, int&>, 0>&’

I've been playing around with this example for ages, but I cannot wrap my head around what's going on. I would be very grateful if anyone could point me into the right direction. Sorry again if this is a stupid question.

Many thanks!

bch
  • 23
  • 3

1 Answers1

0

Most likely, the views return references to the underlying sequence, but somewhere down the line it gets too complicated (I haven't actually dug down the error chain).

What usually helps is to interpose a simpler sequence.

Using as_vector:

Live On Coliru

#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/zip_view.hpp>
#include <boost/fusion/include/view.hpp>

using namespace boost;

int main()
{
    typedef fusion::vector<int, int, int> Tuple3;
    Tuple3 v1(1,2,3);
    Tuple3 v2(4,5,6);

    typedef fusion::vector<Tuple3&, Tuple3&> VVector;
    VVector vv(v1,v2);

    typedef fusion::zip_view<VVector> ZipView;
    auto zv = fusion::as_vector(ZipView(vv));
    typedef fusion::flatten_view<decltype(zv)> FlattenView;
    auto fv = FlattenView(zv);

    // proof of the pudding:
    auto first = fusion::begin(fv);
}

You will think "if I can afford to copy the values" but from the looks of it, the compiler might still generate identical object code anyways, so be sure to check your needs before optimizing.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Thank you so much for your quick and helpful response! That solved my problem completely, nesting views is no longer a problem now. – bch Jan 30 '15 at 09:25