Как расширить содержимое mpl :: set в качестве параметров шаблона шаблона функции - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть шаблон функции с переменным числом параметров шаблона:

template <typename T1, typename... Ts>
void doSomething()
{
    ...
}

Кроме того, у меня есть набор mpl, определенный следующим образом:

template <typename... Ts>
struct MyContainerCreator
{
    using type = boost::mpl::set<Ts...>;
};

using MyContainer= MyContainerCreator<T1, T2>;

Теперь я хочу написатьФункция doSomethingForAll (), которая вызывает doSomething () с типами в mpl, заданными в качестве параметров шаблона.Что-то вроде:

void doSomethingForAll()
{
    //pseudocode:
    doSomething<expandTypesToTemplateParameters<MyContainer::type>>();
}

Возможно ли это?

1 Ответ

0 голосов
/ 21 ноября 2018

По сути, вам нужна функция подъема, которая отображает template<class...> class TT с mpl::set<Ts...> на TT<Ts...>.

. Для этого, как правило, пишите lifter с помощью 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;
    };
};

Тогда вы можете использовать контейнер lift mpl следующим образом:

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;

Тогда u равно foo<int, long>, v равно foo<int, long> или foo<long, int> зависит от mpl внедрение.

С помощью этого инструмента ваша задача может быть выполнена:

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_();
}
...