且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

具有默认参数的成员函数指针

更新时间:2022-06-27 02:40:50

期望函数指针指向是很奇怪的以您期望他们在示例中工作的方式工作。 默认参数是一个纯粹的编译时概念,它是语法糖的一种形式。尽管默认参数是在函数声明或定义中指定的,但它们实际上与函数本身无关。实际上,默认参数在调用时被替换,即在 caller 的上下文中进行处理。从函数的角度来看,用户提供的显式参数与编译器隐式提供的默认参数之间没有区别。

It would be rather strange to expect the function pointers to work the way you expect them to work in your example. "Default argument" is a purely compile-time concept, it is a form of syntactic sugar. Despite the fact that default arguments are specified in the function declaration or definition, they really have nothing to do with the function itself. In reality default arguments are substituted at the point of the call, i.e. they are handled in the context of the caller. From the function's point of view there's no difference between an explicit argument supplied by the user or a default one implicitly supplied by the compiler.

另一方面,函数指针是运行时实体。它们在运行时初始化。在运行时,默认参数根本不存在。在C ++中没有运行时默认参数这样的概念。

Function pointers, on the other hand, are run-time entities. They are initialized at run time. At run-time default arguments simply don't exist. There's no such concept as "run-time default arguments" in C++.

某些编译器将允许您在函数指针声明中指定默认参数,如

Some compilers will allow you to specify default arguments in function pointer declaration, as in

void foo(int);

int main() {
   void (*pfoo)(int = 42) = foo;
   pfoo(); // same as 'pfoo(42)'
}

但这不是标准的C ++而且这似乎不是您要查找的内容,因为您希望在运行时根据指针所指向的函数更改默认参数值。

but this is not standard C++ and this does not appear to be what you are looking for, since you want the "default argument " value to change at run time depending on the function the pointer is pointing to.

只要您想使用真正的函数指针(而不是函数对象,也就是函子),立即的解决方法就是为您提供函数名称的无参数版本,例如

As long as you want to stick with genuine function pointers (as opposed to function objects, aka functors) the immediate workaround would be for you to provide a parameter-less version of your function under a different name, as in

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 所做的工作可能已经被编译器作为语言功能隐式完成了。例如。给定的类定义

One can actually argue that what I did above with bar_default could have been implicitly done by the compiler, as a language feature. E.g. given the class definition

class MyObj 
{ 
public: 
  ...
  int bar(int val = 42) { return 2; } 
  ...
}; 

一个人可能希望编译器允许以下操作

one might expect the compiler to allow the following

int main() 
{ 
  MyObj o; 

  typedef int (MyObj::*barptr2)(); 
  barptr2 bp2 = &MyObj::bar;
  int r3 = (o.*bp2)(); 
  return 0; 
} 

其中指针初始化实际上将迫使编译器隐式生成适配器 MyObj :: bar 的函数(与上一个示例中的 bar_default 相同),并设置 bp2 指向该适配器。但是,目前C ++语言中没有此类功能。并且要引入类似的内容比乍看起来似乎需要付出更多的努力。

where the pointer initialization would actually force the compiler to implicitly generate an "adapter" function for MyObj::bar (same as bar_default in my previous example), and set bp2 to point to that adaptor instead. However, there's no such feature in C++ language at this time. And to introduce something like that would require more effort than it might seem at the first sight.

还要注意,在最后两个示例中,指针类型为 int(MyObj :: *)(),与 int(MyObj :: *)(int)不同。这实际上是一个问题(因为您在示例中都尝试过):希望它如何工作?使用 int(MyObj :: *)()指针吗?还是使用 int(MyObj :: *)(int)指针?

Also note that in the last two examples the pointer type is int (MyObj::*)(), which is different from int (MyObj::*)(int). This is actually a question to you (since you tried both in your example): how would you want it to work? With an int (MyObj::*)() pointer? Or with a int (MyObj::*)(int) pointer?