我试图使用带有默认参数的函数作为函数指针模板参数:
template <void (*F)()>
class A {};
void foo1(int a = 0) {}
void foo2() {}
int main()
{
//A<foo1> a1; <-- doesn't work
A<foo2> a2;
}编译器错误是:
main.cpp:7:7:错误:无法将模板参数‘foo1’转换为‘void(*)()’
是否有特定的语法使其工作?还是特定的语言限制?否则,另一种方法是有两个单独的函数,而不是一个默认参数:
void foo1(int a) {}
void foo1() { foo1(0); }更新我知道签名是不同的,但我想知道是否有一种方法可以方便地完成这项工作,而不需要修改所有带有默认参数的函数?
发布于 2012-11-16 23:05:24
根据C++标准第8.3.6节,
如果在参数声明中指定了表达式,则该表达式将用作默认参数。默认参数将在后面缺少参数的调用中使用。
由于A<foo1>不是函数的调用,默认参数将被忽略。事实上,除了函数的调用之外,它们在所有上下文中都被忽略,例如
typedef void (*FFF)();
FFF x = foo1;将不会编译,并产生与尝试使用foo1作为模板参数时得到的相同消息:
error: invalid conversion from ‘void (*)(int)’ to ‘void (*)()’这是有意义的,因为计算默认参数是调用中的一个单独步骤:
8.3.6.9:每次调用函数时都会计算默认参数。
默认参数的存在不会改变函数的签名。例如,不能使用带有默认参数的单参数函数来覆盖无参数虚拟成员函数。
发布于 2012-11-16 23:00:17
foo1的签名是void(int),而不是void()。这就是它不能转换为void(*)()的原因。
您将默认参数与重载混淆。
发布于 2012-11-16 23:00:09
默认参数值不是函数类型的一部分。您不能使用foo1作为不带参数的函数,因为它确实有一个参数。如果你不提的话,这个论点就会被你填满,但它仍然存在。
涉及调度功能的解决方案听起来是一个很好的解决方案。如果你非常需要它,它甚至可以是模板。
https://stackoverflow.com/questions/13425618
复制相似问题