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

时间:2016-05-07 21:31:54

标签: c++ templates c++14 variadic-templates stdtuple

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

  • 未给出参数的数量
  • 类型都是相同的,但未知(即使它们必须是默认的可构造的)

在运行时,标准容器 for 循环可以用来做到这一点。
无论如何,我想在编译时生成一组参数,以便能够将它们转发到可变参数函数。
因此,std::tuple似乎是一个明显的解决方案。

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

我正在寻找类似的东西:

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

On SO是基于递归生成器的notable example结构,但是我正在努力使用基于函数的解决方案而且我无法在任何地方找到它。

2 个答案:

答案 0 :(得分:5)

正确编写的转发函数(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>{}); } 

答案 1 :(得分:0)

以下是这种功能的可能实现:

#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作为类型 只需很少的努力,就可以使用用户定义的类型,并且可以放宽使其具有默认构造的约束。