Почему конструктор работает с типом функции

Есть такая структура:

template<class Func >
class Call
{
    Func* funcPtr;

public:
    Call(Func* func) :funcPtr{ func }
    {
        std::cout << typeid(Func).name() << std::endl;
    };

Если создаю объект так, то все ок:

Call<decltype(Beep)> a(Beep);

Если меняю тип в конструкторе на Func вместо Func* тоже все норм.

И тут уже вопрос, почему второй вариант работает, ведь Func будет типом функции а не указателем на функцию. Как мы можем создавать переменную типа функции?...


Ответы (1 шт):

Автор решения: HolyBlackCat

В параметрах функций автоматически происходит замена: если тип параметра - функция, то он заменяется на указатель на эту функцию. Более известно похожее правило, по которому в параметрах функций массивы заменяются на указатели.

То же самое происходит в типах (не-ти́повых) шаблонных параметров.

[dcl.fct]/5

any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”.

→ Ссылка