Ответ 1
Если T
- тип, то T*
обозначает тип "pointer-to-T
".
Тип void(int)
- это тип функции, это тип функции, принимающей один int
и возвращающий void
. Например, это тип f
, если f
объявлен как void f(int);
Если T = void(int)
, то T*
пишется void(*)(int)
, поэтому последний является типом указателя функции. Вы также можете создать ссылку на функцию, которая T& = void(&)(int)
; это иногда более полезно (например, вы можете взять адрес функции lvalue).
Кроме того: Функция lvalues очень легко распадается на указатель на функцию. Вы можете вызвать функцию либо с помощью функции lvalue, либо с помощью указателя функции. При использовании в качестве операнда для оператора косвенности (*
) значение функции исчезает, поэтому вы можете разыскивать указатель снова и снова:
printf("Hello world\n"); // OK
(*printf)("Hello world\n"); // also OK
(****printf)("Hello world\n"); // four-star programmer
Некоторые из единственных случаев, когда функция не распадается, используется при использовании в качестве операнда оператора адреса или при привязке к ссылке:
void f(int); // our example function
void(*p1)(int) = &f; // no decay of "f" here
void(*p2)(int) = f; // "f" decays
void(&r1)(int) = f; // no decay of "f" here
void g(void(&callback)(int), int n) {
callback(n);
}
g(f, 10); // no decay of "f" here
template <typename F, typename ...Args>
decltype(auto) h(F&& callback, Args&&... args) {
return std::forward<F>(callback)(std::forward<Args>(args)...);
}
h(f, 10); // no decay of "f" here