2010-04-28 9 views
10
template <class T> 
void max (T &a ,T &b) 
{}//generic template #1 

template<> void max(char &c, char &d) 
{} //template specializtion #2 

void max (char &c, char &d) 
{}//ordinary function  #3 

Was ist der Unterschied zwischen 1, 2 und 3?Was ist der Unterschied zwischen Template Explicit Specialization und normaler Funktion?

+1

Sie können keine Funktionsvorlagen spezialisieren, der Effekt wäre der gleiche wie bei normalen Überladungen. – AshleysBrain

+5

@AshleysBrain: Das ist falsch. Sie können Funktionsvorlagen spezialisieren. Sie können nur teilweise Spezialisierungen machen. – sbi

+0

Ooh, das habe ich gemeint. Vielen Dank. – AshleysBrain

Antwort

10
  1. ist eine Template-Funktion
  2. eine hohe Spezialisierung der bisherigen Template-Funktion ist (nicht überlastet!)
  3. eine Überlastung der Funktion ist

Hier ein Auszug aus C++ Coding Standards: 101 Rules, Guidelines, and Best Practices :

66) Sie spezialisieren nicht Funktionsschablonen

Funktionschablonen-Spezialisierungen nehmen niemals am Überladen teil: Daher beeinflussen alle Spezialisierungen, die Sie schreiben, nicht, welche Schablone verwendet wird, und dies läuft dem entgegen, was die meisten Leute intuitiv erwarten würden. Wenn Sie statt einer Funktionsschablonenspezialisierung eine Nintemplate-Funktion mit der identischen Signatur geschrieben hätten, wäre die Nontemplate-Funktion immer ausgewählt, weil sie immer als besser als eine Vorlage angesehen wird.

Das Buch berät Sie einen Dereferenzierungsebene hinzufügen, indem Sie die Funktion Vorlage in Form einer Klassenvorlage Implementierung:

#include <algorithm> 

template<typename T> 
struct max_implementation 
{ 
    T& operator() (T& a, T& b) 
    { 
    return std::max(a, b); 
    } 
}; 

template<typename T> 
T& max(T& a, T& b) 
{ 
    return max_implementation<T>()(a, b); 
} 

Siehe auch:

+0

Ich habe gerade die Tippfehler im Code korrigiert, sorry dafür –

+0

hinzugefügt gotw Links, die gleichen wie die von @Michael –

+0

thanx Ich verstand den Punkt :) – Suri

2

Die Übereinstimmungsregeln für Vorlagenparameter unterscheiden sich geringfügig von denen überladener Funktionen. Ein Beispiel dafür, was unterscheidet sich zu sehen, wenn Sie versuchen, max() mit Argumenten verschiedener tyoes aufzurufen:

max(1,'2'); 

Dies wird die überladene Funktion entsprechen, aber weder die Basisvorlage noch die Spezialisierung.

+0

In meinem ersten Lesen des Codes sehe ich keinen Unterschied in den Signaturen zwischen der Überladung und der Spezialisierung, andere als die Vorlage. Warum würde 'max (1, '2')' nicht durch die Spezialisierung erreicht? Genauer gesagt, warum wird "1", ein "int", im Überlastfall in "char" umgewandelt, aber nicht im Spezialisierungsfall? – rcollyer

+0

@rcollyer: Sehen Sie das Zitat * # 66 * in Gregorys Antwort. –

+0

@rcollyer: Die einfache Antwort lautet: _Da der Standard sagt so._ 'template <> void max (...)' ist die Syntax für eine Vorlage __spezialisierung__; 'void max (...)' ist die Syntax für eine Funktion __overload__. Die Regeln zum Abgleichen überladener Funktionen unterscheiden sich von den Regeln zum Abgleichen von Vorlagenspezialisierungen. (Und Überladungen werden _first_ gewählt und nur wenn eine Vorlage ausgewählt wird, werden mögliche Spezialisierungen berücksichtigt.) Warum die Auswahl von Überladungen so viel entspannter ist als die Auswahl von Spezialisierungen, kann ich nicht sagen. Aber ich denke, dass Regeln für Überlastungen jetzt gemacht werden würden, sie würden auch strenger sein. – sbi

Verwandte Themen