如果期望函数指针按照您期望的方式在示例中工作,那将是相当奇怪的。 “默认参数”纯粹是一个编译时概念,它是一种形式句法糖。尽管默认参数是在函数声明或定义中指定的,但它们实际上与函数本身无关。实际上,默认参数在调用时被替换,即它们是在调用的上下文中处理的。caller。从函数的角度来看,用户提供的显式参数与编译器隐式提供的默认参数之间没有区别。
另一方面,函数指针是运行时实体。它们在运行时初始化。在运行时默认参数根本不存在。 C++ 中没有“运行时默认参数”这样的概念。
某些编译器允许您在函数指针声明中指定默认参数,如下所示
void foo(int);
int main() {
void (*pfoo)(int = 42) = foo;
pfoo(); // same as 'pfoo(42)'
}
但这不是标准的 C++,并且这似乎不是您正在寻找的,因为您希望“默认参数”值在运行时根据指针指向的函数进行更改。
只要您想坚持使用真正的函数指针(而不是函数对象,又称函子),直接的解决方法就是以不同的名称提供函数的无参数版本,如下所示
class MyObj
{
public:
...
int bar(int val = 42) { return 2; }
int bar_default() { return bar(); }
};
int main()
{
MyObj o;
typedef int (MyObj::*barptr2)();
barptr2 bp2 = &MyObj::bar_default;
int r3 = (o.*bp2)();
return 0;
}
当然,这远非优雅。
人们实际上可以说我上面所做的事情bar_default
作为一种语言功能,编译器可以隐式完成。例如。给定类定义
class MyObj
{
public:
...
int bar(int val = 42) { return 2; }
...
};
人们可能期望编译器允许以下操作
int main()
{
MyObj o;
typedef int (MyObj::*barptr2)();
barptr2 bp2 = &MyObj::bar;
int r3 = (o.*bp2)();
return 0;
}
其中指针初始化实际上会强制编译器隐式生成一个“适配器”函数MyObj::bar
(与...一样bar_default
在我之前的例子中),并设置bp2
改为指向该适配器。然而,目前C++语言中还没有这样的功能。引入这样的东西需要比乍一看更多的努力。
另请注意,在最后两个示例中,指针类型是int (MyObj::*)()
,这不同于int (MyObj::*)(int)
。这实际上对您来说是一个问题(因为您在示例中尝试了两者):如何you想要它发挥作用吗?与int (MyObj::*)()
指针?或者用一个int (MyObj::*)(int)
指针?