print
является функцией, но это неявное преобразование к типу указателя на функцию. Цитируется cppref:
Функция указатель
Именующего выражение типа функции T может быть неявно преобразуется в prvalue указатель на эту функцию. Это не относится к к нестационарным функциям-членам, поскольку lvalues, которые относятся к , нестатические функции-члены не существуют.
Таким образом, в вашем случае:
int (*p)(int) = print; // Conversion happens.
int (*q)(int) = &print; // Conversion does not happen.
пинки неявного преобразования автоматически, когда это необходимо, чтобы сделать программу компиляции, и не применяется в противном случае.
Что касается вызова функций, то речь идет о встроенном вызове функции вызова ()
. Согласно cppref, встроенный оператор вызова функции применим как к выражению lvalue, которое относится к функции, так и к указателю на функцию. В вашем случае:
p(8); // The function call operator is applied to a pointer to function.
(*p)(8); // The function call operator is applied to an lvalue reference to function.
Для справки (курсив мой):
выражение оператор
вызов функции Встроенный вызов функции, такие как E (A1, A2, A3) , состоит из выражения , которое называет функцию E, а затем, возможно, пустым список выражений A1, A2, A3, ... в скобках.Выражение , что имена функция может быть
а) именующего выражения, которое относится к функции
б) указателя на функцию
...
Я предполагаю, что это просто для удобства , что вам не нужно явно указывать указатели на функции при их использовании для вызова функции. Если вы используете 'typedefs', вы можете работать с указателем функции, не используя никаких' * ', которые imho довольно приятны. – user463035818
Возможный дубликат [Как происходит разыменование указателя функции?] (Http://stackoverflow.com/questions/2795575/how-do-dereferencing-of-a-function-pointer-happen) –
@SimonKraemer спасибо. Но ссылка только объясняет разницу, мой вопрос также включает назначение указателя функции. – sydridgm