Boost Fusion:嵌套 flatten_view 和 zip_view

Boost Fusion: Nesting flatten_view and zip_view

嗨!

我拼命尝试使用 Boost Fusion 嵌套不同的视图。我仍在学习 Fusion 的过程中,如果这是一个愚蠢的问题,我深表歉意。

我的实际场景要复杂得多,但为了说明起见,我会尽量简化它。我有两个融合向量 v1v2,它们本身包含在另一个融合向量 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);

我现在想要实现的是 vv 中包含的向量的交错,即按以下顺序遍历 vv 的惰性视图:

1,4,2,5,3,6

为了实现这一点,我正在考虑嵌套 zipflatten 如下:

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

然而,一旦我开始取消引用 fv 中的元素,就会出现问题。例如:

auto first = fusion::begin(fv);

这会产生以下输出:

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>&’

我已经研究这个例子很多年了,但我无法理解正在发生的事情。如果有人能指出我正确的方向,我将不胜感激。如果这是一个愚蠢的问题,再次抱歉。

非常感谢!

最有可能的是,视图 return 引用了底层序列,但在某处它变得太复杂了(我还没有真正深入挖掘错误链)。

插入一个更简单的序列通常会有帮助。

使用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);
}

你会认为"if I can afford to copy the values"但从表面上看,编译器可能仍然会生成相同的目标代码,所以在优化之前一定要检查你的需求。