Benötigen Vorlagenspezialisierungen eine Vorlagensyntax?

8

Ich habe eine Besucher-Klasse, die dieser ähnelt:

%Vor%

Offensichtlich ist operator()(bool b) eine Spezialisierung der vorhergehenden Template-Funktion.

Allerdings hat es nicht die template<> -Syntax, mit der ich früher vertraut bin, und deklariere dies als Template-Spezialisierung. Aber es kompiliert.

Ist das sicher? Ist das korrekt?

    
Drew Dormann 01.06.2009, 22:22
quelle

5 Antworten

19

Ihr Code ist keine Template-Spezialisierung, sondern eine nicht-Template-Funktion. Da gibt es einige Unterschiede. Der nicht vorlagengestützte Operator () hat Vorrang vor einer Vorlagenversion (für eine exakte Übereinstimmung, aber Typumwandlungen finden dort nicht statt), aber Sie können dennoch den Aufruf der Vorlagenfunktion erzwingen:

%Vor%

In Ihrem Code gibt es keinen großen Unterschied, aber wenn Ihr Code den Template-Parameter-Typ bestehen muss, wird er lustiger:

%Vor%     
David Rodríguez - dribeas 01.06.2009, 22:48
quelle
5

Was Sie hier haben, ist das Überladen von Funktionen. Um die Template-Spezialisierung zu erhalten, benötigen Sie in der Tat die template <> -Syntax. Sie sollten sich jedoch darüber im Klaren sein, dass diese beiden Ansätze, auch wenn sie identisch erscheinen mögen, subtil verschieden sind und sogar der Compiler bei der Auswahl der richtigen Aufruffunktion verloren gehen könnte. Das Auflisten aller möglichen Fälle wäre für diese Antwort ein wenig zu lang, aber Sie sollten überprüfen Herb Sutter GoTW # 49 zum Thema.

    
Luc Touraille 01.06.2009 22:41
quelle
4

Oh, es wird kompiliert. Es wird einfach keine Template-Funktion sein. Sie haben eine reguläre Nicht-Template-Funktion anstelle einer Template-Spezialisierung.

Es ist sicher und wahrscheinlich auch das, was Sie wollen. Das Besuchermuster wird normalerweise durch Überladen implementiert. Spezialisierte Funktionsvorlagen ist sowieso keine gute Idee.

    
Fred Larson 01.06.2009 22:27
quelle
2

Was Sie getan haben, ist keine Template-Serialisierung, sondern Überladen von Funktionen. Es ist sicher.

P.S. Es ist schwer zu sagen, ob es richtig ist oder nicht, ohne zu wissen, was Sie erreichen wollen. Beachten Sie, dass es egal, ob es sich um eine Vorlage oder eine überladene Funktion handelt, Ihr Operator in der Kompilierzeit ausgewählt wird. Wenn Sie eine Laufzeitverteilung benötigen, benötigen Sie Polymorphie, nicht Überladung. Nun, du weißt es wahrscheinlich sowieso; nur für den Fall.

    
Igor Krivokon 01.06.2009 22:32
quelle
2

Sie haben

  • void operator()(bool b) das ist nicht Template-Funktion
  • template< typename T > void operator()(T t) , was ein separater Wert ist Basisvorlage, die überlädt oben

Sie könnten eine vollständige Spezialisierung des zweiten haben, wie in template<> void operator(int i) , was nur berücksichtigt würde, wenn void operator()(bool b) nicht übereinstimmt.

Die Spezialisierung der Basisvorlage wird verwendet, um auszuwählen, welche der Basisvorlagenmethoden aufgerufen werden sollen. In Ihrem Fall haben Sie jedoch eine nicht vorbereitete Methode, die zuerst berücksichtigt wird.

Der Artikel Warum nicht auf Funktionsvorlagen spezialisieren? gibt recht gute Erklärungen dafür, wie die Methode ausgewählt wurde.

Zusammenfassend:

  1. Nicht-Template-Funktionen sind zuerst betrachtet (das ist deine Ebene operator () (bool) oben)
  2. Funktionsbasisvorlagen werden überprüft Zweitens (das ist dein Template Funktion), wird die am meisten spezialisierte Basisvorlage ausgewählt und dann, wenn sie eine Spezialisierung für die exakten Typen hat, die Spezialisierung verwendet wird, ansonsten wird die Basisvorlage mit 'den richtigen' Typen verwendet (siehe Erläuterung im Artikel)

Beispiel:

%Vor%

Sie erhalten Anrufe an:

%Vor%     
stefanB 01.06.2009 23:11
quelle