不带星号的函数指针参数

Function pointer parameter without asterisk

我看过这个接收函数指针作为参数的函数的定义:

double fin_diff(double f(double), double x, double h  = 0.01) {
  return (f(x+h)-f(x)) / h;
}

我习惯看到带星号的这个定义,即:

double fin_diff(double (*f)(double), double x, double h  = 0.01);

你知道为什么第一个定义也是有效的吗?

如果将函数参数指定为函数声明,则编译器本身会将参数隐式调整为函数指针。

这类似于将函数名称作为其他函数的参数传递的情况,例如

fin_diff( func_name, 10.0 );

编译器再次将函数指示符隐式转换为指向函数的指针。

标准说这两个函数是等价的,因为函数参数被调整为指向函数参数的指针:

16.1 Overloadable declarations [over.load]
(3.3) Parameter declarations that differ only in that one is a function type and the other is a pointer to the same function type are equivalent. That is, the function type is adjusted to become a pointer to function type (11.3.5).

在 C 中相同:

6.7.5.3 Function declarators (including prototypes)
8 A declaration of a parameter as ‘‘function returning type’’ shall be adjusted to ‘‘pointer to function returning type’’, as in 6.3.2.1.

指向函数的指针很奇怪。给定一个函数void f();,你可以做

void (*fptr)() = f;
void (*fptr)() = &f;
void (*fptr)() = &&f;
void (*fptr)() = &&&f;

无穷无尽。

类似地,当您通过指向函数的指针调用函数时,您可以这样做

fptr();
(*fptr)();
(**fptr)();
(***fptr)();

无穷无尽。

一切都崩溃了。