Якщо вони споріднені
Давайте на мить припустимо, що Bнасправді є базою D. Тоді для виклику checkобидві версії є життєздатними, оскільки Hostможуть бути перетворені на D* та B* . Це визначена користувачем послідовність переходів, як описано 13.3.3.1.2від Host<B, D>до D*і B*відповідно. Для знаходження функцій перетворення, які можуть перетворити клас, для першої checkфункції синтезуються наступні функції-кандидати відповідно до13.3.1.5/1
D* (Host<B, D>&)
Перша функція перетворення не є кандидатом, тому що B*її неможливо перетворити D*.
Для другої функції існують такі кандидати:
B* (Host<B, D> const&)
D* (Host<B, D>&)
Це два кандидати функції перетворення, які приймають об'єкт хосту. Перший приймає це за посиланням const, а другий - ні. Таким чином, другий є кращим збігом для *thisоб'єкта, який не є const ( аргумент мається на увазі ), 13.3.3.2/3b1sb4і використовується для перетворення B*для другої checkфункції.
Якби видалити Конст, ми мали б такі кандидати
B* (Host<B, D>&)
D* (Host<B, D>&)
Це означатиме, що ми не можемо більше вибирати за допомогою constness. У звичайному сценарії розв’язання перевантаження виклик тепер буде неоднозначним, оскільки зазвичай тип повернення не бере участі у вирішенні перевантаження. Для функцій перетворення, проте, є задній простір. Якщо дві функції перетворення однаково хороші, то тип повернення їх визначає, хто найкраще 13.3.3/1. Таким чином, якби ви видалили const, тоді буде прийнято перше, тому що B*перетворюється краще, B*ніж D*до B*.
Тепер, яка визначена користувачем послідовність переходів краще? Один для другої чи першої функції перевірки? Правило полягає в тому, що визначені користувачем послідовності перетворень можна порівняти, лише якщо вони використовують ту саму функцію перетворення або конструктор відповідно до 13.3.3.2/3b2. Тут саме так: Обидва використовують другу функцію перетворення. Зауважте, що таким чином const є важливим, оскільки він змушує компілятора взяти другу функцію перетворення.
Оскільки ми можемо їх порівняти - який із них кращий? Правило полягає в тому, що виграє краща конверсія від типу повернення функції перетворення до типу призначення (знову ж таки 13.3.3.2/3b2). У цьому випадку D*перетворюється краще, D*ніж до B*. Таким чином, вибирається перша функція, і ми визнаємо спадщину!
Зауважте, що оскільки нам ніколи не потрібно було фактично переходити до базового класу, ми можемо тим самим визнати приватне успадкування, тому що чи можемо ми перетворити з а D*в B*не залежить від форми успадкування відповідно до4.10/3
Якщо вони не пов’язані між собою
Тепер припустимо, що вони не пов'язані у спадок. Таким чином, для першої функції у нас є такі кандидати
D* (Host<B, D>&)
А на другий у нас зараз ще один набір
B* (Host<B, D> const&)
Оскільки ми не можемо перетворити D*в , B*якщо ми не отримали відносини спадкування, ми тепер не маємо спільну функції перетворення між двома послідовностями перетворення певного користувачем! Таким чином, ми були б неоднозначними, якби не той факт, що перша функція - шаблон. Шаблони є другим вибором, коли є не шаблонна функція, яка є однаково хорошою відповідно до 13.3.3/1. Таким чином, ми вибираємо не шаблонну функцію (друга) і визнаємо, що між Bі не існує спадкування між і D!