Ich habe Probleme zu verstehen, warum das Folgende zu einem mehrdeutigen Aufruf führt:
%Vor%Ich würde erwarten, dass die Überladungsversion, die auf das zweite Argument spezialisierter ist als die generische Version, als der beste Kandidat ausgewählt wird. Ich weiß das, wenn ich die Überladungsversion zu
ändere %Vor%Dann ist der Aufruf gut gelöst, was mit der Tatsache zu tun hat, dass X :: type ein vorlagenabhängiger Name ist, aber immer noch nicht herausfinden kann, warum er fehlschlägt. Jede Hilfe wird sehr geschätzt.
Zuerst wählen wir die brauchbaren Kandidaten aus. Das sind:
%Vor%Diese Kandidaten nehmen beide die gleichen Argumente an, haben also äquivalente Konvertierungssequenzen. Es gelten also keine der darauf basierenden Tiebreaker, daher greifen wir auf den letzten möglichen Tiebreaker in [over.match.best] zurück:
Angesichts dieser Definitionen wird eine funktionsfähige Funktion F1 als eine bessere Funktion als eine andere funktionsfähige Funktion definiert F2, wenn für alle Argumente i, ICSi (F1) keine schlechtere Umwandlungssequenz als ICSi (F2) ist, dann [...] F1 und F2 sind Funktionsschablonenspezialisierungen, und die Funktionsvorlage für F1 ist spezieller als die Vorlage für F2 gemäß den in 14.5.6.2 beschriebenen Teilordnungsregeln.
Wir versuchen also, die beiden Funktionsschablonen auf der Grundlage der Regeln für die partielle Sortierung anzuordnen, bei denen ein eindeutiger Typ für jeden Vorlagenparameter synthetisiert wird und versucht wird, einen Vorlagenabzug für jede Überladung durchzuführen. Aber mit einer wichtigen zusätzlichen relevanten Regel aus [temp.deduct.partial]:
Jeder oben angegebene Typ aus der Parametervorlage und der entsprechende Typ aus dem Argument Template werden als die Typen von P und A verwendet. Wenn ein bestimmtes P keine Template-Parameter enthält, die teilnehmen In der Argumentableitung des Templates wird P nicht zur Bestimmung der Reihenfolge verwendet.
Was bedeutet das? Versuchen wir zunächst, die generische Version aus der Überladung abzuleiten. Wir wählen die synthetischen Typen UniqueX
(für X
) und UniqueX_type
(für typename X::type
) und sehen, ob wir die generische Funktion aufrufen können. Dies ist erfolgreich (mit X=UniqueX
und Y=typename X::type
).
Versuchen wir es mit der Umkehrung. Wir wählen eine UniqueX
(für X
) und eine UniqueY
(für Y
) aus und versuchen, die Vorlagenabzüge durchzuführen. Für das erste P / A-Paar ist dies trivialer Erfolg. Für das zweite Argument ist X
jedoch ein nicht-abgeleiteter Kontext, der Ihrer Meinung nach dazu führen würde, dass der Vorlagenabzug fehlschlägt. ABER Gemäß dem fettgedruckten Teil des Angebots überspringen wir dieses P / A-Paar zum Zweck der Bestellung. Nachdem das erste P / A-Paar erfolgreich war, betrachten wir den gesamten Deduktionsprozess als erfolgreich.
Da der Vorlagenabzug in beide Richtungen erfolgreich ist, können wir nicht die eine oder die andere Funktion als spezialisierter auswählen. Da es keine weiteren Tiebreaker gibt, gibt es keinen einzigen bestmöglichen Kandidaten, daher ist der Aufruf mehrdeutig.
Wenn die zweite Überlast geändert wird zu:
%Vor% Der Teil des Prozesses, der sich ändert, ist, dass der Abzug in eine Richtung fehlschlägt. Wir können X=UniqueX
ableiten, aber das zweite Paar hat einen Parameter vom Typ int
und ein Argument vom Typ UniqueY
, das nicht funktioniert, daher schlägt diese Richtung fehl. In umgekehrter Richtung können wir X=UniqueX
und Y=int
ableiten. Das macht diese Überladung spezialisierter als die generische Überladung, also wäre es der letzte Tiebreaker, den ich ursprünglich erwähnt habe.
Beachten Sie als Anhang, dass die teilweise Anordnung von Vorlagen kompliziert ist. Überlegen Sie:
%Vor%Tags und Links c++ templates overload-resolution