使用默认参数作为模板类型的函数

Jar*_*edC 5 c++ templates overloading

我正在尝试使用带有默认参数的函数作为函数指针模板参数:

\n\n
template <void (*F)()>\nclass A {};\n\nvoid foo1(int a = 0) {}\nvoid foo2() {}\n\nint main() \n{\n    //A<foo1> a1;   <-- doesn't work\n    A<foo2> a2;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编译器错误是:

\n\n
\n

main.cpp:7:7: 错误:无法将模板参数 \xe2\x80\x98foo1\xe2\x80\x99 转换为 \xe2\x80\x98void (*)()\xe2\x80\x99

\n
\n\n

是否有特定的语法可以使其工作?或者特定的语言限制?否则,另一种方法是使用两个单独的函数而不是默认参数:

\n\n
void foo1(int a) {}\nvoid foo1() { foo1(0); }\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新\n我知道签名是不同的,但我想知道是否有一种方法可以方便地完成这项工作,而不需要用默认参数修改所有函数?

\n

das*_*ght 2

根据 C++ 标准第 8.3.6 节,

\n\n
\n

如果在参数声明中指定了表达式,则该表达式将用作默认参数。默认参数将在缺少尾随参数的调用中使用。

\n
\n\n

由于A<foo1>不是函数的调用,因此默认参数将被忽略事实上,除了函数的调用之外,它们在所有上下文中都会被忽略,例如

\n\n
typedef void (*FFF)();\nFFF x = foo1;\n
Run Code Online (Sandbox Code Playgroud)\n\n

foo1不会编译,并产生与尝试用作模板参数时收到的相同消息:

\n\n
error: invalid conversion from \xe2\x80\x98void (*)(int)\xe2\x80\x99 to \xe2\x80\x98void (*)()\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是有道理的,因为评估默认参数是调用中的一个单独步骤:

\n\n
\n

8.3.6.9:每次调用函数时都会评估默认参数。

\n
\n\n

默认参数的存在不会改变函数的签名。例如,不能使用带有默认参数的单参数函数来覆盖无参数虚拟成员函数。

\n