I'm using boost::fusion in a project. It is my first time using it and things are getting complicated. Playing around I wrote the following program:
#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;
}
As you see it's very simple. It works fine, except when I uncomment the two lines which are followed by "ERROR". If I uncomment the first i get the following error:
/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
and if i uncomment the second then i get:
/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
According to filter_if online documentation, it returns a model of a Forward Sequence (that's the case of the vector) or a model of an Associative Sequence (which is the case of the map). Therefore, the two lines which are giving errors, should work fine. I'm guessing that I'm missing something obvious here (maybe an include?) but i can't get it working.
thanks in advance for your help