给定大小 N 和类型 T 生成元组的函数

Function to generate a tuple given a size N and a type T

在尝试回复 时,我发现自己需要动态地为可变参数函数创建一堆参数,其中:

在运行时,标准容器for循环可用于执行此操作。
无论如何,我想在编译时生成一组参数,以便能够将它们转发给可变参数函数。
因此,std::tuple 似乎是显而易见的解决方案。

问题来了:给定大小N和编译时的默认可构造类型T,如何编写一个函数来生成给定大小的元组?

我正在寻找这样的东西:

auto tup = gen<MyType, N>();

在 SO 上是一个 基于结构的递归生成器,但我一直在努力寻找基于函数的解决方案,但我无法在任何地方找到它。

以下是此类函数的可能实现:

#include<utility>
#include<tuple>

template<typename T>
constexpr auto
params(std::index_sequence<0>) {
    return std::tuple<T>{};
}

template<typename T, std::size_t I, std::size_t... O>
constexpr auto
params(std::index_sequence<I, O...>) {
    auto tup = std::tuple<T>{ T{} };
    auto seq = std::make_index_sequence<sizeof...(O)>{};
    return std::tuple_cat(tup, params<T>(seq));
}

template<typename T, std::size_t N>
constexpr auto
gen(std::integral_constant<std::size_t, N>) {
    return params<T>(std::make_index_sequence<N>{});
}

int main() {
    auto tup = gen<int>(std::integral_constant<std::size_t, 3>{});
    static_assert(std::tuple_size<decltype(tup)>::value == 3, "!");
}

为了简单起见,我使用 int 作为类型。
稍作努力,就可以使用用户定义的类型,并且可以放宽让它们默认可构造的约束。

正确编写的转发函数(la std::apply)应该与 std::array<T, N> 和任何其他实现 std::tuple_size/std::get 接口的东西一起工作。也就是说,

template<size_t, class T>
using T_ = T;

template<class T, size_t... Is>
auto gen(std::index_sequence<Is...>) { return std::tuple<T_<Is, T>...>{}; }

template<class T, size_t N>
auto gen() { return gen<T>(std::make_index_sequence<N>{}); }