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

时间:2019-08-10 23:21:38

标签: c++ variadic-templates

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

写为here

  

对于指向函数的指针,有效的参数是指向具有链接功能(或计算为空指针值的常量表达式)的指针。

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

此规则是否对参数包无效?我错过了标准中的某些内容吗?如果是这样,我该如何修复我的代码,而又不将函数指针作为函数参数传递(即,不声明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:

1 个答案:

答案 0 :(得分:4)

您声明了一个 type 参数包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)类型的函数指针。