首页 > 解决方案 > 如何将 mpl::set 的内容扩展为函数模板的模板参数

问题描述

我有一个带有可变数量模板参数的函数模板:

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

这可能吗?

标签: c++c++11variadic-templatestemplate-meta-programmingboost-mpl

解决方案


template<class...> class TT本质上,您需要一个将 a与 a映射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;

然后uis foo<int, long>visfoo<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_();
}

推荐阅读