Get the subset of a parameter pack based on a give

2019-05-19 02:07发布

Okay, this is a really difficult one.

I want to be able to get the subset of a parameter pack by choosing the parameter types at a given set of valid indices and then use that parameter pack as the argument list of a function. 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

I can get the type of a single index, but a set of indices is a bit harder, especially when that set is of a variable size. The syntax for that is:

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

Maybe I can string a bunch of these together, but I'm not sure how to go about expanding indices_t so that I get a pack_index for each value in the list.

1条回答
再贱就再见
2楼-- · 2019-05-19 02:55

If you wrap the arguments into a tuple, it's pretty straight-forward:

#include <tuple>

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

Example input: <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;
}

Output:

std::tuple<double, char>

All you need to do is use std::tuple<args_t...> where you have just args_t... at the moment.


Here's an alternative idea for structuring that idea into something easier to handle:

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)
    {
        // ...
    }
};

Usage:

selector<int, char, bool, double>::call<0, 2>(1, true);   // int, bool
查看更多
登录 后发表回答