Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 展平(序列的)序列_C++_Boost_Boost Fusion - Fatal编程技术网

C++ 展平(序列的)序列

C++ 展平(序列的)序列,c++,boost,boost-fusion,C++,Boost,Boost Fusion,我正在使用boost::fusion 假设我有如下内容: make_vector(1, make_vector('b', 3, make_vector(4, 5.5), "six"), 7, 8) 我想产生一个函数f,这样 f(make_vector(1, make_vector('b', 3, make_vector(4, 5.5), "six"), 7, 8)) -> [1, 'b', 3, 4, 5.5, "six", 7, 8] i、 e.序列的扁平版本 我不介意这是原始序列

我正在使用boost::fusion

假设我有如下内容:

make_vector(1, make_vector('b', 3, make_vector(4, 5.5), "six"), 7, 8)
我想产生一个函数f,这样

f(make_vector(1, make_vector('b', 3, make_vector(4, 5.5), "six"), 7, 8)) 
-> [1, 'b', 3, 4, 5.5, "six", 7, 8]
i、 e.序列的扁平版本

我不介意这是原始序列的视图还是实际的向量

如果C++0x可以在GCC4.5.1上编译,我不介意它的解决方案

注:

虽然我不想限制数据元素,但如果有帮助的话,可以随意要求“数据”元素都派生自一个公共基类

i、 e


我想,然后你可以通过使用“is_base_of”来计算出数据元素是什么。这里有一个可能的解决方案,递归使用。基本上,它执行以下操作(在伪Haskell中):

递归地,扁平的头部连接到扁平的尾部

这个解决方案很可能不是最有效的,因为它构造了许多视图,甚至是单个值;更好的方法是在递归调用中将结果序列作为参数传递,并直接在其中添加各个元素,可能使用

下面是代码(免责声明:我写得很快,因此代码中可能会充满bug和/或非惯用的操作方式):

的命名空间结果 { 模板 结构展平\u impl { typedef boost::fusion::单视图::type >扁平化层序; typedef typename 展平\u impl::type, 终点 >::键入FlattedTailSequence; typedef typename boost::fusion::result_of::join::type; }; 模板 结构展平\u impl< 开始, 结束,typename boost::如果< boost::fusion::traits::is_sequence::type > >::类型 > { typedef typename boost::fusion::result_of::value_of::type headSequence; typedef typename 展平\u impl::type,typename boost::fusion::result_of::end::type >::类型展平头序列; typedef typename 展平\u impl::type, 终点 >::键入FlattedTailSequence; typedef typename boost::fusion::result_of::join::type; }; 模板 结构展平\u impl { typedef boost::fusion::vector<>类型; }; 模板 结构展平 { typedef typename 展平\u impl::type,typename boost::fusion::result_of::end::type >::类型类型; }; } 模板 typename结果\u of::展平\u impl::type 展平应用程序( const Begin&Begin, const End&End,typename boost::禁用_if< boost::fusion::traits::is_sequence::type > >::类型*dummy=0) { typedef result_of::flatte_impltraits; typedef typename traits::flattedHeadSequence-headSequence; typedef typename traits::flattedTailSequence tailSequence; 返回boost::fusion::join( headSequence(boost::fusion::deref(begin)), 展平(boost::fusion::next(begin),end)); } 模板 typename结果\u of::展平\u impl::type 展平应用程序( const Begin&Begin, const End&End,typename boost::启用_if< boost::fusion::traits::is_sequence::type > >::类型*dummy=0) { typedef result_of::flatte_impltraits; typedef typename traits::flattedHeadSequence-headSequence; typedef typename traits::flattedTailSequence tailSequence; typedef typename boost::fusion::result_of::value_of::type headType; const headType&head=boost::fusion::deref(开始); 返回boost::fusion::join( 展平(boost::fusion::begin(head),boost::fusion::end(head)), 展平(boost::fusion::next(begin),end)); } 模板 typename结果\u of::展平\u impl::type 展平(常数结束和,常数结束和) { 返回boost::fusion::make_vector(); } 模板 typename结果_of::flatte::type 展平(常数序列和序列) { 返回flant_impl(boost::fusion::begin(seq),boost::fusion::end(seq)); }
WOW!谢谢,我试试这个,再仔细看看。这看起来很像我正在浏览的一些boost源代码。我也基于Haskell版本的想法,但如果没有编译错误,我无法获得正确的enable_if。
class DataBase {}

template <class T>
class Data : public DataBase
{
public:
  Data(const T& x) : m_x(x)
  T m_x;
}

template <class T>
T make_data(const T& x) { return Data<T>(x); }
make_vector(
  make_data(1), 
  make_vector(
    make_data('b'), 
    make_data(3), 
    make_vector(
      make_data(4), 
      make_data(5.5)
    ), 
    make_data("six")
  ), 
  make_data(7), 
  make_data(8)
)
flatten []     = []
flatten x      = [x]
flatten (x:xs) = flatten x ++ flatten xs
namespace result_of
{
    template < typename Begin, typename End, class Enable = void >
    struct flatten_impl
    {
        typedef boost::fusion::single_view< typename 
            boost::fusion::result_of::value_of< Begin >::type 
        > flattenedHeadSequence;

        typedef typename 
            flatten_impl< typename
                boost::fusion::result_of::next< Begin >::type,
                End
            >::type flattenedTailSequence;

        typedef typename boost::fusion::result_of::join< const flattenedHeadSequence, const flattenedTailSequence >::type type;
    };


    template < typename Begin, typename End >
    struct flatten_impl< 
        Begin, 
        End, typename
        boost::enable_if< 
            boost::fusion::traits::is_sequence< typename
                boost::fusion::result_of::value_of< Begin >::type
            >
        >::type 
    >
    {
        typedef typename boost::fusion::result_of::value_of< Begin >::type headSequence;
        typedef typename 
            flatten_impl< typename
                boost::fusion::result_of::begin< headSequence >::type, typename
                boost::fusion::result_of::end< headSequence >::type 
            >::type flattenedHeadSequence;

        typedef typename 
            flatten_impl< typename
                boost::fusion::result_of::next< Begin >::type,
                End
            >::type flattenedTailSequence;

        typedef typename boost::fusion::result_of::join< const flattenedHeadSequence, const flattenedTailSequence >::type type;
    };


    template < typename End, typename Enable >
    struct flatten_impl< End, End, Enable >
    {
        typedef boost::fusion::vector< > type;
    };


    template < typename Sequence >
    struct flatten
    {
        typedef typename 
            flatten_impl< typename 
                boost::fusion::result_of::begin< Sequence >::type, typename 
                boost::fusion::result_of::end< Sequence >::type 
            >::type type;
    };    
}


template < typename Begin, typename End >
typename result_of::flatten_impl< Begin, End >::type 
flatten_impl( 
    const Begin & begin, 
    const End & end, typename 
    boost::disable_if<
        boost::fusion::traits::is_sequence< typename
            boost::fusion::result_of::value_of< Begin >::type
        >
    >::type * dummy = 0 )
{
    typedef result_of::flatten_impl< Begin, End > traits;
    typedef typename traits::flattenedHeadSequence headSequence;
    typedef typename traits::flattenedTailSequence tailSequence;

    return boost::fusion::join( 
        headSequence( boost::fusion::deref( begin ) ),
        flatten_impl( boost::fusion::next( begin ), end ) );
}


template < typename Begin, typename End >
typename result_of::flatten_impl< Begin, End >::type 
flatten_impl( 
    const Begin & begin, 
    const End & end, typename 
    boost::enable_if<
        boost::fusion::traits::is_sequence< typename
            boost::fusion::result_of::value_of< Begin >::type
        >
    >::type * dummy = 0 )
{
    typedef result_of::flatten_impl< Begin, End > traits;
    typedef typename traits::flattenedHeadSequence headSequence;
    typedef typename traits::flattenedTailSequence tailSequence;

    typedef typename boost::fusion::result_of::value_of< Begin >::type headType;

    const headType & head = boost::fusion::deref( begin );

    return boost::fusion::join(
        flatten_impl( boost::fusion::begin( head ), boost::fusion::end( head ) ),
        flatten_impl( boost::fusion::next( begin ), end ) );
}


template < typename End >
typename result_of::flatten_impl< End, End >::type
flatten_impl( const End &, const End &)
{
    return boost::fusion::make_vector( );
}


template < typename Sequence >
typename result_of::flatten< Sequence >::type 
flatten( const Sequence & seq )
{
    return flatten_impl( boost::fusion::begin( seq ), boost::fusion::end( seq ) );
}