Jest w tym kilka elementów, które pozwalają wszystkim kombinacjom operatorów działać w ten sam sposób.
Podstawowym powodem, dla którego wszystkie z tych działań jest to, że funkcja (podobna foo
) jest domyślnie konwertowalna na wskaźnik do funkcji. Właśnie dlatego void (*p1_foo)() = foo;
działa: foo
jest domyślnie konwertowany na wskaźnik do siebie i ten wskaźnik jest przypisany p1_foo
.
Jednoargumentowy &
, po zastosowaniu do funkcji, daje wskaźnik do funkcji, podobnie jak podaje adres obiektu, gdy zostanie zastosowany do obiektu. W przypadku wskaźników do zwykłych funkcji zawsze jest redundantny z powodu niejawnej konwersji funkcji na wskaźnik funkcji. W każdym razie właśnie dlatego void (*p3_foo)() = &foo;
działa.
Jednoargumentowy *
, po zastosowaniu do wskaźnika funkcji, daje funkcję wskazaną do, podobnie jak daje obiekt wskazany, gdy jest stosowany do zwykłego wskaźnika do obiektu.
Reguły te można łączyć. Rozważ swój przykład od drugiego do ostatniego **foo
:
- Po pierwsze,
foo
jest domyślnie konwertowany na wskaźnik do siebie, a pierwszy *
jest stosowany do tego wskaźnika funkcji, dając foo
ponownie funkcję .
- Następnie wynik jest ponownie domyślnie konwertowany na wskaźnik do siebie, a drugi
*
jest stosowany, ponownie dając funkcję foo
.
- Następnie jest ponownie domyślnie konwertowany na wskaźnik funkcji i przypisywany do zmiennej.
Możesz dodać dowolną liczbę *
s, wynik jest zawsze taki sam. Im więcej *
s, tym lepiej.
Możemy również rozważyć Twój piąty przykład &*foo
:
- Po pierwsze,
foo
jest domyślnie konwertowany na wskaźnik do siebie; jednoargumentowy *
jest stosowany, ustępując foo
ponownie.
- Następnie
&
stosuje się do foo
, uzyskując wskaźnik do foo
, który jest przypisany do zmiennej.
&
Mogą być stosowane tylko do funkcji chociaż nie do funkcji, które zostały zamienione na wskaźnik funkcyjnych (o ile, oczywiście, wskaźnik funkcji jest zmienna, przy czym wynik jest wskaźnik do a-pointer- do funkcji; na przykład możesz dodać do swojej listy void (**pp_foo)() = &p7_foo;
).
Oto dlaczego &&foo
nie działa: &foo
nie jest funkcją; jest wskaźnikiem funkcji, który jest wartością. Jednak &*&*&*&*&*&*foo
działałoby to tak , jakby działało, &******&foo
ponieważ w obu tych wyrażeniach &
zawsze jest stosowane do funkcji, a nie do wskaźnika funkcji wartości.
Zauważ też, że nie trzeba używać unarnego, *
aby wykonać połączenie za pomocą wskaźnika funkcji; oba (*p1_foo)();
i (p1_foo)();
mają ten sam wynik, ponownie z powodu konwersji funkcji na wskaźnik funkcji.
&foo
przyjmuje adresfoo
, co powoduje, że wskaźnik funkcji wskazuje nafoo
, jak można by się spodziewać.