Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::mpl typelist function application

I have a function that I want to perform on all the types in a typelist (currently represented by an mpl list --- is this even a reasonable way to approach it?)

The key here is that the function only cares about the type, not actual data; it calls a static function in that type to retrieve some information and then does shoves it into a hash table for later reference.

However, as far as I can tell, the mpl does not have a means of doing this --- the closest I can find is the mpl for_each operator, but it appears to want to be used on actual instantiations of each of the types, not the types themselves.

The Loki library had an "apply" function, which is more or less what I am looking for -- it got around the instantiation issue by passing a pointer to the type in the typelist as a parameter to help with deduction, but not doing a full instantiation. What should I be looking at in the MPL to get that functionality? Or am I missing something obvious?

like image 403
Kozaki Avatar asked Dec 29 '11 17:12

Kozaki


2 Answers

You can use for_each "overload" with TransformOp to avoid instantiating the types:

struct functor
{
    template<class T> void operator()( mpl::identity<T> )
    {
        std::cout << typeid(T).name()  << '\n';
    }
};

mpl::for_each<types, mpl::make_identity<_> >( functor() );
like image 97
agurtovoy Avatar answered Nov 17 '22 14:11

agurtovoy


The easiest option just might just be this:

#include <boost/mpl/vector.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/for_each.hpp>
#include <typeinfo>
#include <iostream>

struct functor{
    template<class T>
    void operator()(T*){
        std::cout << typeid(T).name()  << '\n';
    }
};

int main(){
    namespace mpl = boost::mpl;
    using namespace mpl::placeholders;
    typedef mpl::vector<char, int, float, bool> typelist;
    typedef mpl::transform<typelist, boost::add_pointer<_1>>::type ptypelist;
    mpl::for_each<ptypelist>(functor());
}
like image 3
Xeo Avatar answered Nov 17 '22 13:11

Xeo