5

我正在寻找一种方法来创建一个Boost.Fusion序列包装器,它本身就是一个Fusion序列,并将所有“调用”转发到它的包装序列。有点像

template< typename Sequence >
struct sequence_wrapper
{
    explicit sequence_wrapper( Sequence const& s ) : seq( s ){}

    Sequence seq;
};

wheresequence_wrapper< Sequence >也是一个Fusion序列,并且可以正常工作Sequence。我需要这个的原因是我有几个在Fusion序列上运行的函数(其中所有元素都满足一些特殊要求),并且我想添加一些语法糖,我需要一个自定义类型来添加重载运算符。我也不需要对 sequence_wrapper 的操作结果来返回一个 sequence_wrapper,只有与语法糖相关的调用会返回一个(手动)包装的序列。例如,使用逗号运算符将元素附加到序列(有点像Boost.Assign for Fusion序列):

template< typename Sequence, typename T >
sequence_wrapper<
    typename boost::fusion::result_of::push_back<
        Sequence const&
      , T
    >::type
> operator ,( Sequence const& seq, T const& v )
{
    return
        sequence_wrapper<
            typename boost::fusion::result_of::push_back<
                Sequence const&
              , T
            >::type
        >( boost::fusion::push_back( seq, v ) )
        ;
}

实现这一目标的最佳方法是什么(如果图书馆确实支持它)?我特别想避免从头开始创建Fusion序列,因为我想使用Fusion操作返回的任何序列。继承+特化tag_of返回包装序列的标签是否有效?还是我需要定义自己的标签并实现所有必需的功能来转发呼叫?

4

1 回答 1

4

这就是我最终做的事情:

template<
    typename Derived
  , typename Sequence
  , typename TraversalTag = 
        typename boost::fusion::traits::category_of< Sequence >::type
  , typename IsView =
        typename boost::fusion::traits::is_view< Sequence >::type
>
class fusion_sequence_wrapper
  : public boost::fusion::sequence_facade< Derived, TraversalTag, IsView >
{
    typedef Sequence base_sequence_type;

public:
    explicit fusion_sequence_wrapper( base_sequence_type const& sequence )
      : _seq( sequence )
    {}

    base_sequence_type const& base() const
    {
        return _seq;
    }
    base_sequence_type& base()
    {
        return _seq;
    }

public:
    template< typename Seq >
    struct begin
    {
        typedef
            typename boost::fusion::result_of::begin<
                typename boost::mpl::if_<
                    boost::is_const< Seq >
                  , base_sequence_type const
                  , base_sequence_type
                >::type
            >::type type;

        static type call( Seq& s ){ return boost::fusion::begin( s._seq ); }
    };

    template< typename Seq >
    struct end
    {
        typedef
            typename boost::fusion::result_of::end<
                typename boost::mpl::if_<
                    boost::is_const< Seq >
                  , base_sequence_type const
                  , base_sequence_type
                >::type
            >::type type;

        static type call( Seq& s ){ return boost::fusion::end( s._seq ); }
    };

    template< typename Seq >
    struct size
    {
        typedef
            typename boost::fusion::result_of::size<
                typename boost::mpl::if_<
                    boost::is_const< Seq >
                  , base_sequence_type const
                  , base_sequence_type
                >::type
            >::type type;

        static type call( Seq& s ){ return boost::fusion::size( s._seq ); }
    };

    template< typename Seq >
    struct empty
    {
        typedef
            typename boost::fusion::result_of::empty<
                typename boost::mpl::if_<
                    boost::is_const< Seq >
                  , base_sequence_type const
                  , base_sequence_type
                >::type
            >::type type;

        static type call( Seq& s ){ return boost::fusion::empty( s._seq ); }
    };

    template< typename Seq, typename N >
    struct at
    {
        typedef
            typename boost::fusion::result_of::at<
                typename boost::mpl::if_<
                    boost::is_const< Seq >
                  , base_sequence_type const
                  , base_sequence_type
                >::type
              , N
            >::type type;

        static type call( Seq& s ){ return boost::fusion::at( s._seq ); }
    };

    template< typename Seq, typename N >
    struct value_at
    {
        typedef
            typename boost::fusion::result_of::value_at<
                typename boost::mpl::if_<
                    boost::is_const< Seq >
                  , base_sequence_type const
                  , base_sequence_type
                >::type
              , N
            >::type type;
    };

private:
    base_sequence_type _seq;
};
于 2012-09-02T23:13:39.137 回答