变长模板参数从整数开始

10

鉴于我拥有该类型

template<int ...Is>
struct A {};

我能否仅通过一个整数d来“生成”类型A<0, 1, 2, 3, 4, 5,..., d>?

我考虑了一些方法,比如

template<int d>
struct B : A<std::index_sequence<d>...> {}

但它没有起作用。

另一种选择是手动进行专门化:

template<int d>
struct B;

template<>
struct B<0>: A<> {};

template<>
struct B<1>: A<0> {};

template<>
struct B<2>: A<0, 1> {};

template<>
struct B<3>: A<0, 1, 2> {};

但显然我不会写 B<3000> b;

[编辑] 我实际的用例比那个要"复杂"一些。我不想重新实现std::integer_sequence,而是想要更复杂的东西。


6
你需要的是 std::make_integer_sequence - Evg
@Evg,你能详细解释一下吗? - Regis Portalez
2
你的编译器可能会在3000个模板参数处崩溃。 - n. m.
如果我没记错的话,这个可以在编译器设置里面找到 :) - Regis Portalez
作为一个愚蠢卑微的Python程序员,为什么会想要这样做呢? - Adam Barnes
@AdamBarnes 做到了这一点: https://github.com/JeWaVe/euler/blob/master/README.md - Regis Portalez
2个回答

16

标准库中已经有您所需的内容 - std::make_integer_sequence。如果您想使用自己的类型 A<...>,可以这样做:

template<int... Is>
struct A {};

template<class>
struct make_A_impl;

template<int... Is>
struct make_A_impl<std::integer_sequence<int, Is...>> {
    using Type = A<Is...>;
};

template<int size>
using make_A = typename make_A_impl<std::make_integer_sequence<int, size>>::Type;

然后针对 A<0, ..., 2999> 编写:

make_A<3000>

那么 make_A_impl 声明是必需的,以解决在一个模板参数列表中无法有两个参数包的限制? - Stack Danny
@StackDanny,我没有完全理解你的问题。make_A_impl用于将std::integer_sequence“解包”为int... - Evg

4
另一种方法是使用函数签名来匹配 A<...> 类型:
#include <type_traits>

template<int ...Is>
struct A {};

namespace details
{
template <int ...Is>
auto GenrateAHelper(std::integer_sequence<int, Is...>) -> A<Is...>;
}

template<int I> 
using GenerateA = decltype(details::GenrateAHelper(std::make_integer_sequence<int, I>()));

static_assert(std::is_same<GenerateA<3>, A<0, 1, 2>>::value, "");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接