Wskaźnik funkcji a odniesienie do funkcji

W poniższym kodzie function-pointer i to, co uważałem za "function-reference" wydaje się mieć identyczną semantykę:

#include <iostream>
using std::cout;

void func(int a) {
    cout << "Hello" << a << '\n';
}
void func2(int a) {
    cout << "Hi" << a << '\n';
}

int main() {
    void (& f_ref)(int) = func;
    void (* f_ptr)(int) = func;

    // what i expected to be, and is, correct:
    f_ref(1);
    (*f_ptr)(2);

    // what i expected to be, and is not, wrong:
    (*f_ref)(4); // i even added more stars here like (****f_ref)(4)
    f_ptr(3);    // everything just works!

    // all 4 statements above works just fine

    // the only difference i found, as one would expect:
//  f_ref = func2; // ERROR: read-only reference
    f_ptr = func2; // works fine!
    f_ptr(5);

    return 0;
}

Używałem gcc w wersji 4.7.2 w Fedorze / Linux

UPDATE

Moje pytania to:
  1. dlaczego wskaźnik funkcji nie wymaga dereferencji?
  2. dlaczego odwołanie do funkcji nie powoduje błędu?
  3. Jest(są) jakaś sytuacja(y), w której muszę użyć jednego nad inne?
  4. Dlaczego f_ptr = &func; działa? Od kiedy func powinno się rozkładać na wskaźnik?
    While f_ptr = &&func; doesn ' t work (implicit conversion from void *)
Author: John, 2013-10-05

3 answers

Funkcje i odwołania do funkcji (tj. id-wyrażenia tych typów) rozpadają się niemal natychmiast na Wskaźniki funkcji, więc wyrażenia func i f_ref faktycznie stają się wskaźnikami funkcji w Twoim przypadku. Możesz również zadzwonić (***func)(5) i (******f_ref)(6), Jeśli chcesz.

Lepiej jest użyć referencji do funkcji w przypadkach, gdy chcesz, aby operator & - działał tak, jakby został zastosowany do samej funkcji, np. &func jest taki sam jak &f_ref, ale &f_ptr jest czymś else.

 12
Author: Kerrek SB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-05 17:22:31

"dlaczego wskaźnik funkcji nie wymaga dereferencji?"

Ponieważ sam IDENTYFIKATOR funkcji jest w rzeczywistości wskaźnikiem do funkcji już:

4.3 konwersja funkcji na wskaźnik
§1 lvalue typu funkcji T można przekształcić do rvalue typu "wskaźnik do T."Wynikiem jest wskaźnik do funkcji.

"dlaczego dereferencja referencji funkcji nie powoduje błąd?"

Zasadniczo można spojrzeć na definiowanie referencji jako definiowanie aliasu (nazwy alternatywnej). Nawet w standardzie w 8.3.2 Reference w części zajmującej się tworzeniem referencji do obiektu, znajdziesz:
"odniesienie może być traktowane jako nazwa obiektu."

Więc kiedy zdefiniujesz referencję:

void (& f_ref)(int) = func;

Daje możliwość używania f_ref prawie wszędzie tam, gdzie można by użyć func, co jest powodem dlaczego:

f_ref(1);
(*f_ref)(4);

Działa dokładnie tak samo jak użycie func bezpośrednio:

func(1);
(*func)(4);
 11
Author: LihO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-05 17:48:17

Zobacz tutaj .

Operator address-of działa tak, jak można się spodziewać, ponieważ wskazuje na funkcję, ale nie można jej przypisać. Funkcje są konwertowane na Wskaźniki funkcji, gdy są używane jako wartości R, co oznacza, że można dereferować wskaźnik funkcji dowolną liczbę razy i uzyskać ten sam wskaźnik funkcji z powrotem.

 2
Author: Dave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:12