我想用一系列不同(非类型)参数调用模板函数foo
,在下限和上限之间取连续的整数值。例如:
template <int K> void foo(){ ... }
int const UPPER = 10, LOWER = 5;
for(int i = LOWER; i <= UPPER; i++)
foo<i>();
这当然不会起作用,因为i
在编译时是不可知的。我正在寻找一种方法来实现这种程序,而不必编写类似的东西:
foo<5>(); foo<6>(); foo<7>(); foo<8>(); foo<9>(); foo<10>();
这尤其是因为我打算将UPPER
和LOWER
从一个执行更改为下一个执行。
我唯一的想法是创建一个整数的常量数组,它将被发送到模板参数:
int const arr[6] = {5, 6, 7, 8, 9, 10};
for(int i = LOWER; i <= UPPER; i++)
foo<arr[i]>();
但是,虽然数组的元素是常量,但在编译时不知道i
,所以arr[i]
也不知道。{1}}。有什么建议吗?
提前谢谢你。
答案 0 :(得分:3)
您可以使用两个模板和std::enable_if
来选择其中一个,具体取决于Lower
是否等于Upper
。
如果他们 相等,我们什么都不做。否则,我们会调用foo<Lower>()
并使用参数Lower + 1
和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>();
}
鉴于此模板,以下行将为foo<K>()
值K
,5
,6
,7
,{{8
调用9
1}},10
。
callFoo<5, 11>();
答案 1 :(得分:3)
您可以使用std::integer_sequence
获取0升序编号的编译时列表,然后添加您的偏移量:
// Here we take the lower bound and the sequence 0 to (Upper - Lower).
// We call foo with each number in the sequence added to the lower bound.
template<int Lower, int... Ints>
void call_foo_with_range_helper(std::integer_sequence<int, Ints...>) {
// A common trick to expand the parameter pack without recursion or fold expressions
(void)std::initializer_list<int>{(foo<Lower + Ints>(), 0)...};
}
// This simply makes it easier for the caller to use.
// We take the lower and upper bounds only.
template<int Lower, int Upper>
void call_foo_with_range() {
call_foo_with_range_helper<Lower>(std::make_integer_sequence<int, Upper - Lower + 1>());
}
int main() {
int const UPPER = 10, LOWER = 5;
call_foo_with_range<LOWER, UPPER>();
}
答案 2 :(得分:0)
据我所知,模板在编译期间被解析为实际结构,所以你必须将int作为参数传递给函数。