Ich habe den folgenden Code:
%Vor% Die Zeile #1
ruft f(T)
auf, während #2
die Zeile f(bool)
aufruft.
Warum passiert das? Und was sind die Regeln für die Auswahl einer überladenen Vorlagenfunktion?
AKTUALISIEREN
Ich habe verstanden, dass der Compiler im ersten Aufruf% code_% nicht ableiten kann, während er versucht, die zweite Funktion aufzurufen, also wird die erste ausgewählt.
Im zweiten Aufruf wird die zweite Funktion als eine bessere Übereinstimmung für gcc angesehen, während die erste unter VS2013 gewählt wird. Wer macht hier das Richtige? Übrigens interessiert mich immer noch die vollständige Beschreibung des Prozesses.
Die unspezialisierten Funktionsvorlagen werden auch als zugrunde liegende Basisvorlagen bezeichnet. Basisvorlagen können spezialisiert sein. Die Überladungsregeln, um zu sehen, welche in verschiedenen Situationen aufgerufen werden, sind ziemlich einfach, zumindest auf einer hohen Ebene:
Nontemplate-Funktionen sind Bürger erster Klasse. Eine einfache alte Nicht-Templat-Funktion, die den Parametertypen sowie jeder Funktionsvorlage entspricht, wird über eine ansonsten so gut funktionierende Vorlage ausgewählt.
Wenn es keine erstklassigen Bürger gibt, die mindestens genauso gut sind, dann werden die Funktions-Basis-Vorlagen als die Bürger der zweiten Klasse als nächstes konsultiert. Welche Funktionsbasisvorlage ausgewählt wird, hängt davon ab, welche am besten passt und ist die "am meisten spezialisierte" (wichtige Anmerkung: diese Verwendung von "spezialisiert" hat merkwürdigerweise nichts mit Vorlagenspezialisierungen zu tun; es ist nur ein unglücklicher Umgangssprache) nach einer Reihe von fair arkane Regeln:
Wenn es klar ist, dass es eine "am meisten spezialisierte" Funktionsbasisvorlage gibt, wird diese verwendet. Wenn diese Basisvorlage für die verwendeten Typen spezialisiert ist, wird die Spezialisierung verwendet, andernfalls wird die Basisvorlage verwendet, die mit den richtigen Typen instanziiert wurde.
Else (wie in Ihrem Fall) Wenn es ein Bindeglied für die "am meisten spezialisierte" Funktionsbasisvorlage gibt, ist der Aufruf mehrdeutig , weil der Compiler nicht entscheiden kann, welche besser passt . Der Programmierer muss etwas tun, um den Anruf zu qualifizieren und sagen, welcher gewünscht ist.
Sonst, wenn es keine Funktionsbasisvorlage gibt, die passend gemacht werden kann, ist der Aufruf schlecht und der Programmierer muss den Code reparieren.
Wenn Sie eine Funktionsbasisvorlage anpassen möchten und möchten, dass diese Anpassung an der Überladungsauflösung teilnimmt (oder immer im Falle einer exakten Übereinstimmung verwendet wird), machen Sie sie zu einer einfachen alten Funktion. keine Spezialisierung. Und wenn Sie Überladungen bereitstellen, vermeiden Sie auch Spezialisierungen.
Das Obige ist ein Auszug aus diesem Beitrag von dem Herb Sutter und in Im hervorgehobenen Punkt können Sie die Ursache Ihres Problems sehen.
BEARBEITEN
Wenn Sie den obigen Code mit Visual Studio 2012 versuchen (tun Sie es nicht), erhalten Sie
schwerwiegender Fehler LNK1179: ungültige oder beschädigte Datei: COMDAT '?? $ f @ _N @@ YAX_N @ Z' duplizieren
was wie hier erklärt wird, weil
Sie haben eine "Trickserei" gemacht, die C ++ ungültig macht, und sie hat den Compiler übergeben, aber Sie haben jetzt eine ungültige * .obj, und es erstickt den Linker.
und die folgende Zeile ist schuld
%Vor%so hat die in der Antwort erklärte Zweideutigkeit keine garantierte Lösung
Eigentlich wollen Sie eine Template-Spezialisierung, die in Ihrem Fall geschrieben werden sollte:
%Vor%Dies funktioniert wie erwartet in VS2012.
Tags und Links c++ templates overload-resolution function-overloading