如何将fusion :: at_c或fusion :: at_key应用于fusion :: filter_if的结果?

时间:2012-01-31 14:22:41

标签: c++ boost-fusion

我在项目中使用boost :: fusion。这是我第一次使用它,事情变得越来越复杂。我在附近写了下面的程序:

#include <iostream>

#include <boost/mpl/bool.hpp>
#include <boost/mpl/placeholders.hpp>

#include <boost/fusion/include/map.hpp>
#include <boost/fusion/include/filter_if.hpp>
#include <boost/fusion/include/pair.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/at_key.hpp>
#include <boost/fusion/include/io.hpp>

#include <boost/type_traits/is_integral.hpp>

#include <iostream>
#include <assert.h>
#include <typeinfo>


struct x{};
struct y{};
struct z{};

using namespace boost;

template <typename FPair>
struct IsIntegral{
    typedef
    typename mpl::bool_<
               is_integral<
                 typename FPair::second_type
               >::value
             > type;
};


template<typename T>
struct inc_imp
{
    void operator()(T&t)
    {
        t++;
    }
};

template<typename id, typename Data>
struct inc_imp<boost::fusion::pair<id,Data> >
{
    void operator ()(boost::fusion::pair<id,Data> &t)
    {
        t.second++;
    }
};

struct inc
{
    template<typename T>
    void operator()(T& t) const
    {
        inc_imp<T>()(t);
    }
};


int main()
{
    typedef fusion::vector<int,double,int,int> v_t;
    typedef fusion::result_of::filter_if<
              fusion::vector<int,double,int,int>
            , is_same<mpl::placeholders::_1, int>
            >::type view_v_t;

    v_t v(1,2,3,4);
    view_v_t const view_v(v);

    fusion::at_c<0>(v)      = 1; // just to test, fine!
    //fusion::at_c<0>(view_v) = 0; // Error1

    std::cout << "vector----------" << std::endl;
    std::cout << view_v << "  " << v << std::endl;
    fusion::for_each(view_v,inc());
    std::cout << view_v << "  " << v << std::endl;

    typedef fusion::map<
              fusion::pair<x,int>
            , fusion::pair<y,int>
            , fusion::pair<z,double>
            > m_t;

    typedef fusion::result_of::filter_if<
              m_t
            , IsIntegral<
                mpl::placeholders::_1
              >
            >::type view_m_t;

    m_t m(10,11,12);
    view_m_t view_m(m);

    fusion::at_key<x>(m)      = 10;// just to test, fine!
    //fusion::at_key<x>(view_m) = 10;// Error2

    std::cout << "map-------------" << std::endl;
    std::cout << view_m << "  " << m << std::endl;
    fusion::for_each(view_m,inc());
    std::cout << view_m << "  " << m << std::endl;

    return 0;
}

如你所见,这很简单。它工作正常,除非我取消注释这两行  其次是“错误”。如果我取消注释第一个,我会收到以下错误:

/usr/include/boost/fusion/sequence/intrinsic/at.hpp: In instantiation of ‘boost::fusion::result_of::at<const boost::fusion::filter_view<boost::fusion::vector<int, double, int, int, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, boost::is_same<mpl_::arg<1>, int> >, mpl_::int_<0> >’:
/usr/include/boost/fusion/sequence/intrinsic/at.hpp:64:   instantiated from ‘boost::fusion::result_of::at_c<const boost::fusion::filter_view<boost::fusion::vector<int, double, int, int, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, boost::is_same<mpl_::arg<1>, int> >, 0>’
../main.cpp:81:   instantiated from here
/usr/include/boost/fusion/sequence/intrinsic/at.hpp:59: error: invalid use of incomplete type ‘struct boost::fusion::extension::at_impl<boost::fusion::filter_view_tag>::apply<const boost::fusion::filter_view<boost::fusion::vector<int, double, int, int, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, boost::is_same<mpl_::arg<1>, int> >, mpl_::int_<0> >’
/usr/include/boost/fusion/sequence/intrinsic/at.hpp:30: error: declaration of ‘struct boost::fusion::extension::at_impl<boost::fusion::filter_view_tag>::apply<const boost::fusion::filter_view<boost::fusion::vector<int, double, int, int, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, boost::is_same<mpl_::arg<1>, int> >, mpl_::int_<0> >’
../main.cpp: In function ‘int main()’:
../main.cpp:81: error: no matching function for call to ‘at_c(const main()::view_v_t&)’
make: *** [main.o] Error 1

如果我取消注释第二个,那么我得到:

/usr/include/boost/fusion/sequence/intrinsic/at_key.hpp: In instantiation of ‘boost::fusion::result_of::at_key<const boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x>’:
../main.cpp:105:   instantiated from here
/usr/include/boost/fusion/sequence/intrinsic/at_key.hpp:55: error: invalid use of incomplete type ‘struct boost::fusion::extension::at_key_impl<boost::fusion::filter_view_tag>::apply<const boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x>’
/usr/include/boost/fusion/sequence/intrinsic/at_key.hpp:29: error: declaration of ‘struct boost::fusion::extension::at_key_impl<boost::fusion::filter_view_tag>::apply<const boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x>’
/usr/include/boost/fusion/sequence/intrinsic/at_key.hpp: In instantiation of ‘boost::fusion::result_of::at_key<boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x>’:
/usr/include/boost/utility/enable_if.hpp:63:   instantiated from ‘boost::lazy_disable_if_c<false, boost::fusion::result_of::at_key<boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x> >’
/usr/include/boost/utility/enable_if.hpp:70:   instantiated from ‘boost::lazy_disable_if<boost::is_const<boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > > >, boost::fusion::result_of::at_key<boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x> >’
../main.cpp:105:   instantiated from here
/usr/include/boost/fusion/sequence/intrinsic/at_key.hpp:55: error: invalid use of incomplete type ‘struct boost::fusion::extension::at_key_impl<boost::fusion::filter_view_tag>::apply<boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x>’
/usr/include/boost/fusion/sequence/intrinsic/at_key.hpp:29: error: declaration of ‘struct boost::fusion::extension::at_key_impl<boost::fusion::filter_view_tag>::apply<boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x>’
In file included from /usr/include/boost/fusion/support/tag_of.hpp:10,
                 from /usr/include/boost/fusion/support/category_of.hpp:11,
                 from /usr/include/boost/fusion/container/map/map.hpp:11,
                 from /usr/include/boost/fusion/container/map.hpp:11,
                 from /usr/include/boost/fusion/include/map.hpp:10,
                 from ../main.cpp:8:
/usr/include/boost/utility/enable_if.hpp: In instantiation of ‘boost::lazy_disable_if_c<false, boost::fusion::result_of::at_key<boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x> >’:
/usr/include/boost/utility/enable_if.hpp:70:   instantiated from ‘boost::lazy_disable_if<boost::is_const<boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > > >, boost::fusion::result_of::at_key<boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x> >’
../main.cpp:105:   instantiated from here
/usr/include/boost/utility/enable_if.hpp:63: error: no type named ‘type’ in ‘struct boost::fusion::result_of::at_key<boost::fusion::filter_view<boost::fusion::map<boost::fusion::pair<x, int>, boost::fusion::pair<y, int>, boost::fusion::pair<z, double>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, IsIntegral<mpl_::arg<1> > >, x>’
../main.cpp: In function ‘int main()’:
../main.cpp:105: error: no matching function for call to ‘at_key(main()::view_m_t&)’
make: *** [main.o] Error 1

根据filter_if online documentation,它返回一个前向序列的模型(即矢量的情况)或一个关联序列的模型(这是地图的情况)。因此,给出错误的两条线应该可以正常工作。我猜我在这里遗漏了一些明显的东西(也许是一个包括?)但是我无法让它发挥作用。

提前感谢您的帮助

0 个答案:

没有答案