如何使用模板模板类型作为函数参数?

时间:2020-09-12 03:21:46

标签: c++

我要实现以下代码:

template <int i>
void f() {
    ...
}
template <template <int i> typename Func>
void g(Func func, int i) {
    if (i == 0) func<0>();
    else if (i == 1) func<1>();
    else if (i == 2) func<2>();
    else assert(false);
}
int main() {
    g(f, 0);
}

但是,此代码无法编译。它显示“错误:缺少模板模板参数“ Func”的参数列表”。我不知道该如何解决。非常感谢!

1 个答案:

答案 0 :(得分:2)

模板可以用作模板的参数,但不能用作函数的参数。因此错误;当您尝试使用模板名称(Func)作为函数参数的类型时,编译器抱怨模板名称本身是不够的。需要模板参数列表来从模板中获取类型,然后才能将其作为函数参数的类型。

您似乎正在尝试将template参数复制为功能参数。不要那样做直接使用template参数。

template <template<int> typename Func>
void g(int i) {
    if (i == 0) Func<0>();
    else if (i == 1) Func<1>();
    else if (i == 2) Func<2>();
    else assert(false);
}

但是,您的设置还有其他问题。如typename关键字所建议,模板模板参数不能是函数模板。 所以这不起作用。 参见Can a template template parameter be of a variable or function?


另一种方法(由OP提出)可能是使用类模板和operator()。一个警告是operator()不能是静态的,因此g还有另一句法上的变化。

template <template<int> typename Func>
void g(int i) {
    if (i == 0) Func<0>{}();      // <
    else if (i == 1) Func<1>{}(); // < -- Invoke operator() on a temporary
    else if (i == 2) Func<2>{}(); // <
    else assert(false);
}

给定一个类模板f,可以通过g<f>(0)调用它。