给定模板 class (A) 和类型的参数包 (T1, T2...),转换为 A<T1>、A<T2>、A[=12= 这样的元组]

Given a template class (A) and a parameter pack of types (T1, T2...), convert to a tuple like A<T1>, A<T2>, A<T3>

你如何实现这个:

template <class A, class ... T> struct wrapper {
   template <int depth>
   A<depth>& get(); // returns a reference to the Nth item wrapped in A;
};

例如

wrapper<vector, int, double, string> example;

int x=example.get<0>[7];       // return the vector of `int` at position 0 and call operator[]
auto y=example.get<1>.size();  // return the vector of `double` at position 1 and get it's size

这是我试过的:

template<class A, class ... T>
struct wrapper {
    using WRAPPED=decl_type(std::apply(
        [](auto ...x){
             std::make_tuple(A[x], ...);
        },
        T...));
    WRAPPED elems;

    template <int depth>
    decl_type(std::get<depth>(elems))& get() { return std::get<depth>(elems); }
};

但是编译器不高兴:

<source>:71:23: error: expected type-specifier before 'decl_type'
   71 |         using WRAPPED=decl_type(std::apply(
      |                       ^~~~~~~~~
<source>:74:14: error: expected unqualified-id before ',' token
   74 |             },
      |              ^
<source>:76:9: error: 'WRAPPED' does not name a type
   76 |         WRAPPED elems;
      |         ^~~~~~~
<source>:79:24: error: 'std::get' is not a type
   79 |         decl_type(std::get<depth>(elems))& get() { return std::get<depth>(elems); }
      |                        ^~~~~~~~~~
<source>:79:44: error: expected constructor, destructor, or type conversion before 'get'
   79 |         decl_type(std::get<depth>(elems))& get() { return std::get<depth>(elems); }
      |                                            ^~~
Compiler returned: 1

您需要 template-template 个参数。

std::tuple 也可能有帮助:

template <template <typename, typename...> class C, typename... Ts>
struct wrapper
{
    template <std::size_t I>
    std::tuple_element_t<I, std::tuple<C<Ts>...>>& get()
    {
        return std::get<I>(data);
    }

    std::tuple<C<Ts>...> data;
};

// Possible usage
void test(wrapper<std::vector, int, double, std::string>& example)
{
    [[maybe_unused]]int x = example.get<0>()[7];      // vector of `int`
    [[maybe_unused]]auto y = example.get<1>().size(); // vector of `double`
}

Demo

注意:std::vector有超过1个模板参数(默认有分配器)。