C ++ - Vorlage Funktionen Überladung Auflösung

8

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.

    
lisyarus 14.03.2014, 17:07
quelle

2 Antworten

12

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

    
Nikos Athanasiou 14.03.2014, 17:23
quelle
1

Eigentlich wollen Sie eine Template-Spezialisierung, die in Ihrem Fall geschrieben werden sollte:

%Vor%

Dies funktioniert wie erwartet in VS2012.

    
HiroshimaCC 10.10.2014 13:19
quelle