使用多个参数值调用模板函数

时间:2016-06-21 12:55:05

标签: c++ templates non-type

我想用一系列不同(非类型)参数调用模板函数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>();

这尤其是因为我打算将UPPERLOWER从一个执行更改为下一个执行。

我唯一的想法是创建一个整数的常量数组,它将被发送到模板参数:

int const arr[6] = {5, 6, 7, 8, 9, 10};

for(int i = LOWER; i <= UPPER; i++)
    foo<arr[i]>();

但是,虽然数组的元素是常量,但在编译时不知道i,所以arr[i]也不知道。{1}}。有什么建议吗?

提前谢谢你。

3 个答案:

答案 0 :(得分:3)

您可以使用两个模板和std::enable_if来选择其中一个,具体取决于Lower是否等于Upper。 如果他们 相等,我们什么都不做。否则,我们会调用foo<Lower>()并使用参数Lower + 1Upper进行递归。

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>()K567,{{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作为参数传递给函数。