Разница между void (int) & void (*) (int)

Я знаю, что void (*)(int) - это функция указателя, но что такое void(int)?

Используется для шаблона std::function.

Скажем, у меня есть функция void fun(int){}: decltype(&fun) дает void(*)(int), но decltype(fun) дает void(int)

Ответ 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

Ответ 2

void (*whatever)(int) 

следует читать как: любой указатель, указывающий на функцию, которая принимает один int как аргумент и ничего не возвращает (т.е., void).

void whatever(int)

следует читать как: независимо от функции (НЕ указатель), которая принимает один int как аргумент и ничего не возвращает (т.е., void)

Как только указатель на функцию инициализируется, чтобы указать на действительную функцию (удовлетворяющую прототипу), вы можете вызвать функцию либо через ее "реальное" имя, либо через указатель.

Указатели на функции очень полезны - они являются переменными, как и все остальное, поэтому вы можете передавать их другим функциям (см., например, qsort()), вы можете поместить их в структуры и т.д.

Учитывая это, действует следующий код:

#include <stdio.h>

void myfun(int x) {
  printf("The value of X is %d\n", x);
}

int main() {
    void (*myfunp)(int);

    myfunp = &myfun;

    myfun(13);
    myfunp(12);

    return 0;
}

Ответ 3

void(*)(int) следует читать как тип указателя, который указывает на function, который принимает один аргумент int в качестве аргумента и ничего не возвращает.

Чтобы узнать больше о функции для указателя и его использовании, пожалуйста, проверьте здесь: http://www.cprogramming.com/tutorial/function-pointers.html