Jika mereka terkait
Mari sejenak kita asumsikan bahwa B
itu sebenarnya adalah basis D
. Kemudian untuk panggilan ke check
, kedua versi tersebut layak karena Host
dapat diubah menjadi D*
dan B*
. Ini adalah urutan konversi yang ditentukan pengguna seperti yang dijelaskan oleh 13.3.3.1.2
dari Host<B, D>
ke D*
dan B*
masing - masing. Untuk menemukan fungsi konversi yang dapat mengonversi kelas, fungsi kandidat berikut disintesis untuk check
fungsi pertama menurut13.3.1.5/1
D* (Host<B, D>&)
Fungsi konversi pertama bukanlah kandidat, karena B*
tidak dapat dikonversi menjadi D*
.
Untuk fungsi kedua, ada kandidat berikut:
B* (Host<B, D> const&)
D* (Host<B, D>&)
Itu adalah dua kandidat fungsi konversi yang mengambil objek host. Yang pertama mengambilnya dengan referensi const, dan yang kedua tidak. Jadi yang kedua lebih cocok untuk objek non-const *this
( argumen objek tersirat ) oleh 13.3.3.2/3b1sb4
dan digunakan untuk mengonversi ke B*
untuk check
fungsi kedua .
Jika Anda ingin menghapus const, kami akan memiliki kandidat berikut
B* (Host<B, D>&)
D* (Host<B, D>&)
Ini berarti bahwa kita tidak dapat lagi memilih dengan konstan. Dalam skenario resolusi kelebihan beban biasa, panggilan tersebut sekarang menjadi ambigu karena biasanya jenis kembalian tidak akan berpartisipasi dalam resolusi kelebihan beban. Untuk fungsi konversi, bagaimanapun, ada pintu belakang. Jika dua fungsi konversi sama baiknya, maka jenis kembaliannya memutuskan siapa yang terbaik menurut 13.3.3/1
. Jadi, jika Anda akan menghapus const, maka yang pertama akan diambil, karena B*
bertobat lebih baik untuk B*
daripada D*
untuk B*
.
Sekarang, urutan konversi yang ditentukan pengguna mana yang lebih baik? Yang untuk fungsi pemeriksaan kedua atau pertama? Aturannya adalah bahwa urutan konversi yang ditentukan pengguna hanya dapat dibandingkan jika mereka menggunakan fungsi atau konstruktor konversi yang sama sesuai dengan 13.3.3.2/3b2
. Inilah yang terjadi di sini: Keduanya menggunakan fungsi konversi kedua. Perhatikan bahwa dengan demikian konstanta penting karena memaksa kompiler untuk mengambil fungsi konversi kedua.
Karena kita bisa membandingkannya - mana yang lebih baik? Aturannya adalah bahwa konversi yang lebih baik dari jenis pengembalian fungsi konversi ke jenis tujuan menang (lagi dengan 13.3.3.2/3b2
). Dalam hal ini, D*
mengonversi lebih baik ke D*
daripada B*
. Jadi fungsi pertama dipilih dan kami mengenali warisan!
Perhatikan bahwa karena kita tidak pernah benar - benar perlu mengubah ke kelas dasar, dengan demikian kita dapat mengenali pewarisan pribadi karena apakah kita dapat mengonversi dari a D*
ke a B*
tidak bergantung pada bentuk pewarisan menurut4.10/3
Jika mereka tidak berhubungan
Sekarang anggap saja mereka tidak terkait dengan warisan. Jadi untuk fungsi pertama kami memiliki kandidat berikut
D* (Host<B, D>&)
Dan untuk yang kedua sekarang kita memiliki satu set lagi
B* (Host<B, D> const&)
Karena kami tidak dapat mengonversi D*
menjadi B*
jika kami tidak memiliki hubungan warisan, kami sekarang tidak memiliki fungsi konversi yang sama di antara dua urutan konversi yang ditentukan pengguna! Jadi, kita akan menjadi ambigu jika bukan karena fakta bahwa fungsi pertama adalah template. Template adalah pilihan kedua jika ada fungsi non-template yang juga sama baiknya 13.3.3/1
. Jadi, kami memilih fungsi non-templat (yang kedua) dan kami menyadari bahwa tidak ada warisan antara B
dan D
!