Рассмотрим следующий фрагмент кода
void pf();
void (&prf)() = pf; // OK, bind prf to pf
void (&prf)() = &pf; // ill-formed, can't bind prf to an function pointer value
С другой стороны
void (*ppf)() = pf; // OK, function decays to a pointer
void (*ppf)() = &pf; // OK, pointer assigned to a pointer
Таким образом, существует неявное преобразование из функции в указатель (который называется «распад»). Это также позволяет вам сказать ***...***pf
- произвольно много раз разыменовывая его - на каждом шаге происходит преобразование функции в указатель, которое отменяет эффект предыдущего разыменования.
В списках параметров функции a T f()
и a T (*f)()
являются эквивалентными способами (кроме написания) объявления параметра
void f(void g()); // g has type void (*)()
void f(void (*g)()); // g has type void (*)()
Задание заблокирует настройку этого типа параметра
void f(void (&g)()); // g has *not* the type void (*)()
Это точно так же, как и для объявленных параметров массива: параметры никогда не являются массивами, но они всегда будут указателями, если они были объявлены как массивы.