2014-06-16 10 views
17

Könnte jemand erklären, warum einmal Methode c(T*) und das nächste Mal d<>(int*) verwendet wird? Methoden c und d scheint mir identisch und ich kann nicht herausfinden, warum nicht die gleiche Art von Methode genannt wird.C++ verschiedene Template-Methoden für dieselbe Variable

#include <iostream> 
using namespace std; 

template<typename T> 
void c(T){ cout <<"(T)" << endl; } 

template<> 
void c<>(int*){ cout <<"(int*)" << endl; } 

template<typename T> 
void c(T*){ cout <<"(T*)" << endl; } 

template<typename T> 
void d(T){ cout <<"(T)" << endl; } 

template<typename T> 
void d(T*){ cout <<"(T*)" << endl; } 

template<> 
void d<>(int*){ cout <<"(int*)" << endl; } 

int main(){ 
    int i; 
    c(&i); 
    d(&i); 
    return 0; 
} 

Output:

(T*) 
(int*) 
+1

Sie unterscheiden sich in der Anordnung. – ghostofstandardspast

+0

Bestellmethoden können einen Einfluss haben? – zlenyk

+10

Natürlich können sie. Siehe [Warum Funktionsschablonen nicht spezialisieren?] (Http://www.gotw.ca/publications/mill17.htm) von Sutter, was genau darum geht. – legends2k

Antwort

18

Sie sind gerade auf einen hässlichen Teil von C++ gestoßen.

Die Überladungsauflösung besteht während des Kompilierens darin, die beste Überladung für den aktuellen Code zu finden. Es wird auf einer Reihe von Funktions- und Funktionsschablonen ausgeführt, die in der Nachschlage-Phase ausgewählt wurden, und zielt darauf ab, eine (und nur eine) Überladung zu identifizieren, die besser als andere ist.

Für Funktionsschablonen, sind sie in zwei Gruppen getrennt:

  • "base" Funktionsschablonen
  • Spezialfunktionsschablonen

und die Überlastauflösungsprozess besteht aus zwei Schritten:

  1. Wählen Sie die beste Übereinstimmung zwischen den regulären Funktions- und Basisfunktionsvorlagen
  2. Wenn eine „Basis“ Funktionsvorlage von 1. Schritt ausgewählt wird, die beste Spezialisierung wählen (wenn überhaupt, da sie sonst die „Basis“ verwenden)

In Ihre beiden Beispiele, die beste „Basis“ Funktion ist c(T*) und d(T*), also ist dies der zweite Schritt, der sich unterscheidet. Warum ?

Da die Funktionsvorlage als Spezialisierung einer Funktionsvorlage angegeben werden muss, muss sie zuerst deklariert werden.

So:

  • c<>(int*) ist eine Spezialisierung von c(T)
  • d<>(int*) ist eine Spezialisierung von d(T*)

und daher, wenn c(T*) in Schritt 1 gerichtet, dann gibt es keine bessere Spezialisierung während d(T*) ausgewählt wird, d<>(int*) ist eine bessere Spezialisierung.

Da dies schwierig ist, die Empfehlung von Experten ... ist nicht, Funktion Vorlage Spezialisierung zu verwenden. Es vermischt sich nur komisch mit Überlastung der Funktionsvorlage.

2

Überlastungs Auflösung wählt nur eine Basisvorlage (oder eine nichtcodierende Funktion, wenn einer verfügbar ist). Erst nachdem entschieden wurde, welche Basisvorlage ausgewählt werden soll und diese Auswahl eingeschlossen ist, wird der Compiler sich umsehen, ob es eine geeignete Spezialisierung für diese Vorlage gibt, und wenn diese Spezialisierung verwendet wird.

Für Funktion c die Spezialisierung void c<>(int*) ist für void c(T) Überlastung während für die Spezialisierung dvoid d<>(int*) für void d(T*) Überladung ist.

Also durch die obige Erklärung wird zuerst void c(T) inspiziert und wird über die bessere Überlastung void c(T*) ignoriert (die keine Spezialisierungen hat), die gedruckt wird. Für d ist auch die void d(T*) Überlastung gesperrt, aber dann wird die Spezialisierung void d(int*) notiert und dann gewählt.

15
template <typename T> 
void c(T);  // 1: function template 

template <> 
void c<>(int*); // 2: specialization of 1 

template<typename T> 
void c(T*);  // 3: overload of 1 

template<typename T> 
void d(T);  // 4: function template 

template<typename T> 
void d(T*);  // 5: overload of 4 

template<> 
void d<>(int*); // 6: specialization of 5 

// ... 

int i; 

c(&i);   // 3 is more appropriate overload than 1 

d(&i);   // 5 is more appropriate overload than 4 
       // and it has the suitable specialization 6 

Diagramm:

    c  d 
       /\ /\ 
overloads   1 (3) 4 (5) | 
        |   | | priority 
specializations 2   (6) V 
+0

Das ist eine sehr prägnante Art, die Informationen zu präsentieren, nett :) –

+0

@MatthieuM. Vielen Dank. – Constructor

Verwandte Themen