递归构建一个无符号整数的变长模板

3
我需要一个 C++ 2011 代码中的棘手问题。 目前,我有这样一种元函数:

template<unsigned int N, unsigned int M> 
static constexpr unsigned int myFunction()

这个函数可以基于 NM 生成数字。
我想写一个元函数,输入为 NM,并通过递减 M 递归地构建可变参数模板。例如,通过使用 M = 3 调用此函数,它将构建一个名为 List 的可变参数模板,如下所示:
List... = myFunction<N, 3>, myFunction<N, 2>, myFunction<N, 1>, myFunction<N, 0>

这该怎么做(如果当然可能的话)?

1
最好您能告诉我使用场景,例如您将如何使用它。而且,仅有函数名myFunction<N, 3>并没有括号是没有意义的。一个更详细的带有使用场景的示例会更有帮助。 - Mr.Anubis
1个回答

4

最简单的方法可能是使用现有的元组生成器:

// Idiomatic tuple pack generator using successor method
template<int... I> struct tuple_pack {
    using succ = tuple_pack<I..., sizeof...(I)>;
};
template<int N> struct make_tuple_pack {
    using type = typename make_tuple_pack<N - 1>::type::succ;
};
template<> struct make_tuple_pack<0> {
    using type = tuple_pack<>;
};

现在,我们可以应用元组打包生成器,并委托给一个实现函数:
template<int N, int M, typename T> struct foo_impl {};
template<int N, int M, int... I> struct foo_impl<N, M, tuple_pack<I...>> {
    static void foo() {
        int arr[M] = { myFunction<N, M - I>()... };
    }
};
template<int N, int M> void foo() {
    foo_impl<N, M, typename make_tuple_pack<M>::type>::foo();
}

如果你更喜欢函数参数推导而不是类模板特化,那么可以这样写:
template<int N, int M, int... I> void foo_impl(tuple_pack<I...>) {
    int arr[M] = { myFunction<N, M - I>()... };
}
template<int N, int M> void foo() {
    foo_impl<N, M>(typename make_tuple_pack<M>::type{});
}

我必须指定数组大小为int arr[M]; 不确定这是否要求打包扩展初始化程序符合标准,或者这是gcc中的一个错误; 无论哪种方式都没有太大的麻烦。


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