Wenn sie verwandt sind
Nehmen wir für einen Moment an, dass dies B
tatsächlich eine Basis von ist D
. Für den Aufruf von check
sind dann beide Versionen realisierbar, da Host
sie in D*
und konvertiert werden können B*
. Es ist eine frei wählbare Konvertierungssequenz wie beschrieben 13.3.3.1.2
aus Host<B, D>
an D*
und B*
verbunden. Um Konvertierungsfunktionen zu finden, die die Klasse konvertieren können, werden die folgenden Kandidatenfunktionen für die erste check
Funktion gemäß synthetisiert13.3.1.5/1
D* (Host<B, D>&)
Die erste Konvertierungsfunktion ist kein Kandidat, da B*
sie nicht konvertiert werden kann D*
.
Für die zweite Funktion existieren folgende Kandidaten:
B* (Host<B, D> const&)
D* (Host<B, D>&)
Dies sind die beiden Kandidaten für die Konvertierungsfunktion, die das Hostobjekt übernehmen. Der erste nimmt es als konstante Referenz und der zweite nicht. Somit ist die zweite eine bessere Übereinstimmung für das nicht konstante *this
Objekt (das implizite Objektargument ) von 13.3.3.2/3b1sb4
und wird zum Konvertieren B*
für die zweite check
Funktion verwendet.
Wenn Sie die Konstante entfernen würden , hätten wir die folgenden Kandidaten
B* (Host<B, D>&)
D* (Host<B, D>&)
Dies würde bedeuten, dass wir nicht mehr nach Konstanz auswählen können. In einem normalen Überlastungsauflösungsszenario wäre der Aufruf jetzt mehrdeutig, da der Rückgabetyp normalerweise nicht an der Überlastungsauflösung beteiligt ist. Für Konvertierungsfunktionen gibt es jedoch eine Hintertür. Wenn zwei Konvertierungsfunktionen gleich gut sind, entscheidet der Rückgabetyp, wer der beste ist 13.3.3/1
. Wenn Sie also die Konstante entfernen würden, würde die erste verwendet, da sie B*
besser in B*
als D*
in konvertiert B*
.
Welche benutzerdefinierte Konvertierungssequenz ist nun besser? Die für die zweite oder die erste Prüffunktion? Die Regel ist, dass benutzerdefinierte Konvertierungssequenzen nur verglichen werden können, wenn sie dieselbe Konvertierungsfunktion oder denselben Konstruktor gemäß verwenden 13.3.3.2/3b2
. Genau das ist hier der Fall: Beide verwenden die zweite Konvertierungsfunktion. Beachten Sie, dass die const daher wichtig ist, da sie den Compiler zwingt, die zweite Konvertierungsfunktion zu übernehmen.
Da können wir sie vergleichen - welches ist besser? Die Regel ist, dass die bessere Konvertierung vom Rückgabetyp der Konvertierungsfunktion in den Zieltyp (erneut von 13.3.3.2/3b2
) gewinnt . In diesem Fall D*
konvertiert besser nach D*
als nach B*
. Damit ist die erste Funktion ausgewählt und wir erkennen die Vererbung!
Beachten Sie, dass wir, da wir nie tatsächlich in eine Basisklasse konvertieren mussten, die private Vererbung erkennen können, da es nicht von der Form der Vererbung abhängt, ob wir von a D*
nach a konvertieren könnenB*
4.10/3
Wenn sie nicht verwandt sind
Nehmen wir nun an, sie sind nicht durch Vererbung verbunden. Somit haben wir für die erste Funktion die folgenden Kandidaten
D* (Host<B, D>&)
Und zum zweiten haben wir jetzt ein anderes Set
B* (Host<B, D> const&)
Da wir nicht konvertieren können D*
, B*
wenn wir keine Vererbungsbeziehung haben, haben wir jetzt keine gemeinsame Konvertierungsfunktion zwischen den beiden benutzerdefinierten Konvertierungssequenzen! Daher wären wir nicht eindeutig, wenn nicht die erste Funktion eine Vorlage wäre. Vorlagen sind die zweite Wahl, wenn es eine Nicht-Vorlagenfunktion gibt, die entsprechend gut ist 13.3.3/1
. Daher wählen wir die Nicht-Template-Funktion (zweite) aus und erkennen, dass zwischen B
und D
! Keine Vererbung besteht.