I would like to call a template function foo
with a sequence of different (non-type) parameters, taking consecutive integer values between a lower and upper bound. For instance:
template <int K> void foo(){ ... }
int const UPPER = 10, LOWER = 5;
for(int i = LOWER; i <= UPPER; i++)
foo<i>();
This, of course, won't work since i
is not known at compile time. I am looking for a way to achieve this sort of program without having to write something like:
foo<5>(); foo<6>(); foo<7>(); foo<8>(); foo<9>(); foo<10>();
This is in particular because I intend on changing UPPER
and LOWER
from one execution to the next.
My only idea was to create a constant array of the integers which will be sent to the template parameter:
int const arr[6] = {5, 6, 7, 8, 9, 10};
for(int i = LOWER; i <= UPPER; i++)
foo<arr[i]>();
But, again, although the elements of the array are constant, i
is not known at compile-time so neither is arr[i]
. Any suggestions?
Thank you in advance.
You can use two templates and std::enable_if
to select one of them, depending on whether Lower
is equal to Upper
.
In case they are equal, we do nothing. Otherwise, we invoke foo<Lower>()
and recurse with parameters Lower + 1
and Upper
.
template <int Lower, int Upper>
typename std::enable_if<Lower == Upper, void>::type callFoo()
{
}
template <int Lower, int Upper>
typename std::enable_if<Lower != Upper, void>::type callFoo()
{
static_assert(Lower < Upper, "Lower must be less than or equal to Upper");
foo<Lower>();
callFoo<Lower + 1, Upper>();
}
Given this template, the following line will invoke foo<K>()
for K
values 5
, 6
, 7
, 8
, 9
, 10
.
callFoo<5, 11>();