Ada beberapa bagian yang memungkinkan semua kombinasi operator ini bekerja dengan cara yang sama.
Alasan mendasar mengapa semua pekerjaan ini adalah bahwa suatu fungsi (seperti foo
) secara implisit dapat dikonversi menjadi pointer ke fungsi tersebut. Inilah sebabnya mengapa void (*p1_foo)() = foo;
berfungsi: foo
secara implisit dikonversi menjadi pointer ke dirinya sendiri dan pointer yang ditugaskan p1_foo
.
Unary &
, ketika diterapkan pada suatu fungsi, menghasilkan pointer ke fungsi, sama seperti itu menghasilkan alamat suatu objek ketika diterapkan pada suatu objek. Untuk pointer ke fungsi biasa, selalu redundan karena konversi fungsi-ke-fungsi-pointer implisit. Bagaimanapun, ini sebabnya void (*p3_foo)() = &foo;
bekerja.
Unary *
, ketika diterapkan pada pointer fungsi, menghasilkan fungsi menunjuk-ke, sama seperti itu menghasilkan objek menunjuk-ke ketika itu diterapkan pada pointer biasa ke objek.
Aturan-aturan ini bisa digabungkan. Pertimbangkan contoh kedua hingga terakhir Anda **foo
:
- Pertama,
foo
secara implisit dikonversi menjadi pointer ke dirinya sendiri dan yang pertama *
diterapkan ke pointer fungsi itu, menghasilkan fungsi foo
lagi.
- Kemudian, hasilnya secara implisit dikonversi menjadi pointer ke dirinya sendiri dan yang kedua
*
diterapkan, lagi-lagi menghasilkan fungsi foo
.
- Itu kemudian secara implisit dikonversi ke fungsi pointer lagi dan ditugaskan ke variabel.
Anda dapat menambahkan sebanyak yang *
Anda suka, hasilnya selalu sama. Semakin banyak *
, semakin meriah.
Kami juga dapat mempertimbangkan contoh kelima Anda &*foo
:
- Pertama,
foo
secara implisit dikonversi menjadi pointer ke dirinya sendiri; unary *
diterapkan, menghasilkan foo
lagi.
- Kemudian,
&
diterapkan ke foo
, menghasilkan pointer ke foo
, yang ditugaskan ke variabel.
Namun, &
hanya dapat diterapkan ke fungsi, bukan ke fungsi yang telah dikonversi ke pointer fungsi (kecuali, tentu saja, pointer fungsi adalah variabel, dalam hal ini hasilnya adalah pointer-to-a-pointer- to-a-function; misalnya, Anda dapat menambahkan ke daftar Anda void (**pp_foo)() = &p7_foo;
).
Inilah sebabnya mengapa &&foo
tidak berfungsi: &foo
bukan fungsi; itu adalah pointer fungsi yang merupakan nilai. Namun, &*&*&*&*&*&*foo
akan berfungsi, seperti yang akan terjadi &******&foo
, karena dalam kedua ekspresi &
itu selalu diterapkan pada fungsi dan bukan ke pointer fungsi nilai.
Perhatikan juga bahwa Anda tidak perlu menggunakan unary *
untuk melakukan panggilan melalui penunjuk fungsi; keduanya (*p1_foo)();
dan (p1_foo)();
memiliki hasil yang sama, sekali lagi karena konversi fungsi-ke-fungsi-pointer.
&foo
mengambil alamatfoo
, yang menghasilkan pointer fungsi menunjukfoo
, seperti yang diharapkan.