根据给定的索引集获取参数包的子集

时间:2013-11-03 22:25:56

标签: c++ templates parameters variadic-templates template-meta-programming

好的,这真的很难。

我希望能够通过在给定的一组有效索引中选择参数类型来获取参数包的子集,然后使用该参数包作为函数的参数列表。 IE:

template <size_t... indices_t>
void func(pack_subset<indices_t..., args_t...>); //incorrect syntax,
                                                 //not sure how else to write this
                                                 //args_t is predetermined, this
                                                 //function is a static member of
                                                 //a variadic class template

//For a parameter pack <float, double> and index set 0
void func(float); // <- result of template

我可以获得单个索引的类型,但是一组索引更难一些,特别是当该集合具有可变大小时。其语法是:

pack_index<size_t index_t, typename... args>::type

也许我可以将这些内容串起来,但我不知道如何扩展indices_t,以便为列表中的每个值获取pack_index。

1 个答案:

答案 0 :(得分:5)

如果将参数包装到元组中,那么它非常简单:

#include <tuple>

template <typename T, std::size_t ...Is>
struct selector
{
    using type = std::tuple<typename std::tuple_element<Is, T>::type...>;
};

示例输入:<int, double, float, char, bool>, 1, 3

#include <iostream>
#include <demangle.hpp>

int main()
{
    std::cout
        << demangle<selector<std::tuple<int, double, float, char, bool>, 1, 3>::type>()
        << std::endl;
}

输出:

std::tuple<double, char>

您需要做的只是使用std::tuple<args_t...>,而您目前只有args_t...


以下是将该想法构建为更易于处理的内容的另一种想法:

template <typename ...Args> struct selector
{
    using T = std::tuple<Args...>;

    template <std::size_t ...Is>
    static void call(typename std::tuple_element<Is, T>::type ...args)
    {
        // ...
    }
};

用法:

selector<int, char, bool, double>::call<0, 2>(1, true);   // int, bool