Параметр указателя функции без звездочки
Я видел это определение функции, которая получает указатель на функцию в качестве параметра:
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);
Знаете ли вы, почему первое определение также верно?
Ответы
Ответ 1
Стандарт говорит, что эти две функции эквивалентны, так как аргументы функции настроены так, чтобы быть указателем на аргументы функции:
16.1 Перегружаемые объявления [over.load]
(3.3) Объявления параметров, которые отличаются только тем, что один является типом функции, а другой является указателем на тот же тип функции, эквивалентны. То есть тип функции настраивается, чтобы стать указателем на тип функции (11.3.5).
то же самое в C:
6.7.5.3 Деклараторы функций (включая прототипы)
8 Объявление параметра как типа, возвращающего функцию, должно быть настроено на указатель на тип, возвращающий функцию, как в 6.3.2.1.
Ответ 2
Указатели на функции своеобразны. Дана функция void f();
, ты можешь сделать
void (*fptr)() = f;
void (*fptr)() = &f;
void (*fptr)() = &&f;
void (*fptr)() = &&&f;
до бесконечности.
Точно так же, когда вы вызываете функцию через указатель на функцию, вы можете сделать
fptr();
(*fptr)();
(**fptr)();
(***fptr)();
до бесконечности.
Все рушится.
Ответ 3
Если параметр функции указан как объявление функции, то сам компилятор неявно корректирует параметр как указатель функции.
Это похоже на то, когда имя функции передается в качестве аргумента какой-либо другой функции, как, например,
fin_diff( func_name, 10.0 );
компилятор снова неявно преобразует указатель функции в указатель на функцию.