I need a tricky thing in a C++ 2011 code. Currently, I have a metafunction of this kind :
template<unsigned int N, unsigned int M>
static constexpr unsigned int myFunction()
This function can generate number based on N and M.
I would like to write a metafunction with input N and M, and that will recursively construct a variadic template by decrementing M. For example, by calling this function with M = 3, It will construct a variadic template called List equal to :
List... = myFunction<N, 3>, myFunction<N, 2>, myFunction<N, 1>, myFunction<N, 0>
How to do that (if it is possible of course) ?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With