Reputation: 121
I have a function template with a variadic number of template parameters:
template <typename T1, typename... Ts>
void doSomething()
{
...
}
Furthermore I have an mpl set defined as follows:
template <typename... Ts>
struct MyContainerCreator
{
using type = boost::mpl::set<Ts...>;
};
using MyContainer= MyContainerCreator<T1, T2>;
Now I want to write a function doSomethingForAll() that calls doSomething() with the types in the mpl set as template parameters. Something like:
void doSomethingForAll()
{
//pseudocode:
doSomething<expandTypesToTemplateParameters<MyContainer::type>>();
}
Is this possible?
Upvotes: 1
Views: 119
Reputation: 16404
Essentially you want a lifting function that maps a template<class...> class TT
with a mpl::set<Ts...>
to TT<Ts...>
.
To do this generically, write a lifter
with the help of Foldable:
template<template<class...> class TT>
struct lifter {
template<class Foldable>
struct apply {
template <class Left, class Current> struct one_stepper;
template<class... Ts, class Current>
struct one_stepper<TT<Ts...>, Current> {
using type = TT<Ts..., Current>;
};
using type = typename mpl::fold<Foldable, TT<>,
one_stepper<mpl::_1, mpl::_2>
>::type;
};
};
Then you can use lift mpl container in this way:
template<class... Ts> struct foo {};
using u = lifter<foo>::apply<mpl::vector<int, long>>::type;
using v = lifter<foo>::apply<mpl::set<int, long>>::type;
Then u
is foo<int, long>
, v
is foo<int, long>
or foo<long, int>
depends on mpl
implementation.
With this tool, your task can be done by:
template<class... Ts>
struct doSomething_helper {
static void do_() { doSomething<Ts...>(); }
};
void doSomethingForAll()
{
//pseudocode:
// doSomething<expandTypesToTemplateParameters<MyContainer::type>>();
lifter<doSomething_helper>::apply<typename MyContainer::type>::type::do_();
}
Upvotes: 3