如何访问模板类型参数包中的类型索引?

das*_*ght 4 c++ templates c++11

我想在将类型参数包扩展为std::tuple<...>.

例如,给定一个类型包,<int, double, float>我想构建一个std::tuple<...>如下所示的:

std::tuple<std::array<int,0>, std::array<double,1>, std::array<float, 2>>
//                     ^  ^                ^    ^                ^    ^
//                     T  I                T    I                T    I
Run Code Online (Sandbox Code Playgroud)

这是一个实现几乎完全符合我的要求,但它仅适用于大小为 3 的类型包(请参阅 hack 旁边的注释)。如何解决此问题以独立于TT...s 大小工作?

#include <tuple>
#include <utility>
#include <array>
#include <iostream>

template <typename... TT>
struct Foo {
    template <std::size_t... Indices>
    struct Baz {
       std::tuple<std::array<TT,Indices>...> baz;
    };
    Baz<0,1,2> bar; // <<<=== Here is the hack: I make a fixed-size pack; I want it to match TT...
};

int main() {
    Foo<int,double,float> foo;
    std::cout << std::get<0>(foo.bar.baz).size() << std::endl;
    std::cout << std::get<1>(foo.bar.baz).size() << std::endl;
    std::cout << std::get<2>(foo.bar.baz).size() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现场演示。

for*_*818 5

你在嵌套的正确轨道上有两个包。您现在需要的是一个std::integer_sequence可以让您创建所需的包,而不是通过Baz<0,1,2> bar;.

基本思想是定义一个函数模板,该模板std::integer_sequence<size_t,I...>对包进行参数化并使用 a 调用它,std::make_integer_sequence<size_t,N>以便I...可以从单个数字推导出包N,然后它只是折叠:

#include <tuple>
#include <utility>
#include <array>
#include <iostream>
#include <utility>
#include <type_traits>

template <typename...Ts>
struct foo {
    static const size_t N = sizeof...(Ts);
    template <size_t ... I>
    static auto helper(std::integer_sequence<size_t,I...>){
        return std::tuple<std::array<Ts,I>...>{};
    }
    using type = decltype(helper(std::make_integer_sequence<size_t,N>{}));
};

int main() {
    std::cout << std::is_same< std::tuple<std::array<int,0>, std::array<double,1>, std::array<float, 2>>,
                 foo<int,double,float>::type >::value;
}
Run Code Online (Sandbox Code Playgroud)

现场演示

  • @2b-t:OP 已经使用了 `std::array&lt;Ts, Indices&gt;...` 顺便说一句。 (2认同)