почему (* callback) () работает, а не * callback () или * callback в c ++ - PullRequest
3 голосов
/ 02 марта 2020

Я - начинающий студент C ++, и я подумал, что для того, чтобы по-настоящему выучить указатели и ссылки, я должен попытаться сделать функцию обратного вызова, что я воспринимаю как должное в JavaScript.

Но для жизни я не знаю, почему эти скобки так важны в (*callback)(), и я бы с удовольствием, если бы кто-нибудь смог мне это объяснить.

Вот код, который я написал и который каким-то образом работал:

#include<cstdio>

void function_two()
{
    printf("then this runs!");
}

void function_one(void (*callback)() = nullptr)
{
    printf("this runs first");
    if(callback != nullptr)
    {
        (*callback)();
    }
}

int main()
{
    function_one(&function_two);
}

Ответы [ 3 ]

7 голосов
/ 02 марта 2020

Фактически вы можете просто написать

callback();

Если вы используете унарный оператор разыменования *, он имеет более низкий приоритет по сравнению с оператором вызова функции postfix. Поэтому вы должны написать

(*callback)();

В противном случае такой вызов

*callback();

рассматривается компилятором как разыменование результата вызова функции.

Имейте в виду что даже можно написать как

(******callback)();

, потому что в выражениях указатель функции преобразуется в указатель на функцию.

6 голосов
/ 02 марта 2020

*callback() вызывает operator() в callback, затем разыменовывает (*) результат вызова этой функции.

(*callback)() разыменовывает callback, а затем вызывает operator() в результате этой разыменования.

Две очень разные вещи.

*callback просто разыменовывает указатель, но ничего не делает с результатом. Семантически допустимо, но ничего не делает в этом контексте.

См. Также Приоритет оператора C ++

1 голос
/ 02 марта 2020

почему (* callback) () работает, а не * callback () или * callback в c ++

*callback() не работает, потому что функция возвращает void. Выражение void не может быть операндом.

*callback «работает» в том смысле, что оно является правильно сформированным выражением. Это, однако, не выражение вызова функции, поэтому вы не вызывали никакой функции, выполняя это.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...