为什么这个参数包不能接受函数指针?

Why can't this parameter pack accept function pointers?

我正在尝试创建一个充满函数指针的参数包,但是 GCC(使用 c++17 标准)生成了一个 deduction failed 错误。这是为什么?

写成here

For pointers to functions, the valid arguments are pointers to functions with linkage (or constant expressions that evaluate to null pointer values).

在我的示例中,就是这种情况(不是吗?)。

此规则是否对参数包无效?我错过了标准中的某些内容吗?如果是这样,我该如何修复我的代码,而不将函数指针作为函数参数传递(即不声明 T run2(T input, Funcs... funcs).

// In f.hpp
template<typename T>
T run2(T input)
{
    return input;
}

template<typename T, T(*f)(T), class ... Funcs>
T run2(T input)
{
    return run2<T, Funcs...>(f(input));
}

// In m.cpp
unsigned add2(unsigned v)
{
    return v+2;
}

int main()
{
    unsigned a=1;
    a = run2<unsigned, add2>(a); // works
    a = run2<unsigned, add2, add2>(a); // doesn't work
    std::cout << a << std::endl;

    return 0;
}

这是我在 run2<unsigned, add2, add2> 中遇到的错误(GCC 没有告诉我上次尝试实际上失败的原因):

m.cpp: In function ‘int main()’:
m.cpp:37:37: error: no matching function for call to ‘run2(unsigned int&)’
     a = run2<unsigned, add2, add2>(a);
                                     ^
In file included from m.cpp:2:0:
./f.hpp:85:3: note: candidate: template<class T> T run2(T)
 T run2(T input)
   ^
./f.hpp:85:3: note:   template argument deduction/substitution failed:
m.cpp:37:37: error: wrong number of template arguments (3, should be 1)
     a = run2<unsigned, add2, add2>(a);
                                     ^
In file included from m.cpp:2:0:
./f.hpp:109:3: note: candidate: template<class T, T (* f)(T), class ... Funcs> T run2(T)
 T run2(T input)
   ^
./f.hpp:109:3: note:   template argument deduction/substitution failed:

您声明了一个类型参数包,class... Funcs。您不能将函数指针作为参数传递给 type 参数,因为它们是值,而不是类型。相反,您需要声明 run2 模板,使其具有函数指针模板参数包。这样做的语法如下:

template<typename T, T(*f)(T), T(*...fs)(T)>
T run2(T input)
{
    return run2<T, fs...>(f(input));
}

(规则是 ...declarator-id 的一部分,并且正好在标识符之前,即 fs。)

fs可以接受一个或多个T (*)(T)类型的函数指针。