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

Nmd*_*ery 2 c++ parameters templates template-meta-programming variadic-templates

好的,这真的很难.

我希望能够通过在给定的一组有效索引中选择参数类型来获取参数包的子集,然后使用该参数包作为函数的参数列表.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
Run Code Online (Sandbox Code Playgroud)

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

pack_index<size_t index_t, typename... args>::type
Run Code Online (Sandbox Code Playgroud)

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

Ker*_* SB 5

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

#include <tuple>

template <typename T, std::size_t ...Is>
struct selector
{
    using type = std::tuple<typename std::tuple_element<Is, T>::type...>;
};
Run Code Online (Sandbox Code Playgroud)

输入示例: <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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

std::tuple<double, char>
Run Code Online (Sandbox Code Playgroud)

您需要做的就是使用目前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)
    {
        // ...
    }
};
Run Code Online (Sandbox Code Playgroud)

用法:

selector<int, char, bool, double>::call<0, 2>(1, true);   // int, bool
Run Code Online (Sandbox Code Playgroud)