boost::mpl typelist function application
Asked Answered
T

3

7

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?

Thirzia answered 29/12, 2011 at 17:44 Comment(2)
Can you use C++11? If not, I believe MPL is the only way without reinventing everything. (Or you could use macros...)Sag
@Kenny: I think the point is that MPL does not provide the functionality wanted here.Julietjulieta
R
8

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() );
Recalescence answered 30/12, 2011 at 3:23 Comment(1)
I ended up going with this one --- it seems to work exactly as advertised, and makes more sense to me. Thank you much!Thirzia
J
3

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());
}
Julietjulieta answered 29/12, 2011 at 18:47 Comment(0)
D
0

Do the same thing in MPL: Call boost::mpl::transform with boost::add_pointer to make a sequence of pointers to your types, and then use boost::mpl::for_each.

Daysidayspring answered 29/12, 2011 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.