It's probably simplest to use an existing tuple pack generator:
// 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<>;
};
Now we can apply the tuple pack generator, delegating to an implementation function:
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();
}
If you prefer function parameter inference to class template specialisation this could also be written as:
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.