3

I'm trying to create a filter_view from fusion map, but can't seem to get the template meta function to work.

So I have a fusion map with a structure similar to this

#include <boost/fusion/container/map.hpp>
#include <boost/fusion/view/filter_view.hpp>

template <typename> struct SetField { };
using IDType = int;
using NameType = std::string;
using TimeField = double;

using namespace boost::fusion;
typedef map<pair<struct ActId,  SetField<IDType> >,
            pair<struct ActName, SetField<NameType> >,
            pair<struct ActStart, TimeField>,
            pair<struct ActEnd,   TimeField> > ActivityMapType;

I want to create a filter_view the excludes the fields where the second type is a TimeField

int main()
{
    ActivityMapType map_;
    filter_view<
            ActivityMapType const, 
            boost::mpl::not_<boost::is_same<result_of::second<boost::mpl::_>::type, TimeField>>
        > view(map_);
}

The compiler error I get is

 /home/mike/boost/boost/fusion/support/pair.hpp: In instantiation of
             'struct boost::fusion::result_of::second<mpl_::arg<-1> >':
 /home/mike/project/Filter/FusionActivityFilter.h:328:55:   required
 from here /home/mike/boost/boost/fusion/support/pair.hpp:68:48: error:
 no type named 'second_type' in 'struct mpl_::arg<-1>'
              typedef typename Pair::second_type type;

I wonder if I'm just using the boost::mpl::_ placeholder incorrectly, I'm new to this meta programming stuff.

mike
  • 3,339
  • 6
  • 30
  • 34
  • 2
    If you want help, perhaps you should make the sample code self-contained. People will just skip the question if they can't even make the code compile. – sehe Mar 14 '14 at 15:31
  • Could it be just `boost::mpl::not_>`? It compiles at least… (MPL beginner here) – Simon Mar 14 '14 at 16:27
  • So I've figured out a little more. Just as a test I did boost::mpl::not_ > >. It seems the pair as a whole is passed in as a single argument to the _1 placeholder. I haven't figured out how to access the individual types that make up the pair though. – mike Mar 18 '14 at 15:20

1 Answers1

1

Well I found a solution that is essentially the answer given here

template <typename FPair>
struct get_second 
{
   typedef typename FPair::second_type type;
};

int main()
{
    ActivityMapType map_;
    typedef boost::fusion::result_of::filter_if<
                       boost::mpl::lambda<
                               boost::mpl::not_<
                                        boost::is_same<
                                                  TimeField,
                                                  get_second<boost::mpl::_1>
                                        >
                               >
                       >::type
            >::type no_time_type;
    no_time_type noTimes(map_);
}

I don't quite understand why I couldn't do the same thing with the boost::fusion::filter_view. I thought I found a boost ticket open for what seemed like a potential reason, but I can't find it now. It seems filter_view prevents the actual type of the placeholder _1 from being seen by the inner meta-functions.

Community
  • 1
  • 1
mike
  • 3,339
  • 6
  • 30
  • 34