3

我在 C++ 2011 代码中需要一个棘手的东西。目前,我有这种元功能:

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

此函数可以根据N和生成数字M

我想用输入N和编写一个元函数M,它将通过递减递归构造一个可变参数模板M。例如,通过使用 调用此函数M = 3,它将构造一个称为List等于的可变参数模板:

List... = myFunction<N, 3>, myFunction<N, 2>, myFunction<N, 1>, myFunction<N, 0>

怎么做(如果可能的话)?

4

1 回答 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{});
}

I had to specify the array size as int arr[M]; not sure whether that's required by the standard for pack expansion initializers or whether it's a bug in gcc; either way it's no big hassle.

于 2012-09-05T15:31:35.647 回答