2010-09-26 15 views
8

C++ Standard-Unterschied zwischen Vorlagennamen und Template-ID

Abschnitt 14/2:

In einer Funktion Template-Deklaration, der declarator-id soll ein Template-Name seine (dh kein Template-ID). [Hinweis: in einer Klasse Template-Deklaration, wenn die declarator-id ist ein Template-id, die Deklaration deklariert eine Klasse Vorlage partielle Spezialisierung.

Was ist der Unterschied zwischen einem template-name, template-id und type-id?

Ist das obige Zitat bedeuten können wir nicht so etwas wie

template <> 
void templatefunction<int>(){ // ...} 

schreiben oder habe ich den Punkt falsch verstanden?

Antwort

29

Die Schablonenname ist der Name der Vorlage. In Ihrem Beispiel ist templatefunction ein Vorlagenname.

Die Vorlagen-ID ist der Name der Vorlage mit der Liste der Vorlagenargumente. In Ihrem Beispiel ist templatefunction<int> die Template-ID. Eine Vorlage-ID benennt eine Vorlagenspezialisierung.

Eine Typ-ID nennt einen Typ. A Vorlage-ID ist eine Typ-ID; a Schablonenname ist nicht (weil es keinen Typ nennt; es benennt eine Vorlage).

Der von Ihnen zitierte Text bezieht sich auf eine Vorlage-Deklaration, die eine primäre Vorlage deklariert. Ihr Beispiel ist keine Vorlage-Deklaration, es ist eine explizite Spezialisierung (14.7.3/1).

2

Von C++ Templates: The Complete Guide Von David Vandevoorde, Nicolai M. Josuttis

8.3

Explizite Template Argumente: Ein Vorlagennamen durch explizite Template-Argument Werte in spitzen Klammern gefolgt werden kann. Der resultierende Name wird als Vorlage-ID bezeichnet.

Zum Beispiel:

template <typename T> 
struct Demo{ 
    // ... 
}; 

int main() 
{ 
    Demo <int> d; // Demo is the template name, Demo<int> is the template-id 
    // ... 
} 

In Abhängigkeit Template-Deklaration, die declarator-ID wird eine Vorlage-name (das heißt, kein Templat-ID) sein.

Zum Beispiel (aus dem, was ich verstanden habe):

class A { 
public: 
    template <typename T> void f(T); 
    template <typename T> struct X { }; 
}; 
class B : public A { 
public: 
    using A::f;  // fine 
    using A::X  // fine 

}; 
class C : public A { 
public: 
    using A::f<int>;  // ill formed, declarator-id shall not be a template id 
    using A::X<double> // ill formed, declarator-id shall not be a template id 

}; 

Jemand bitte korrigieren Sie mich, wenn ich falsch bin.

6

Eine Deklarator-ID ist das syntaktische Element, das den Namen in einer einfachen Deklaration ("Typname;") angibt. Im folgenden "A" und "B :: C" ist der declarator-id

int A; 
int B::C; 
int A(); 
int *A; 
int A[42]; 
template<typename T> void A(); 

A-Typ-ID syntaktisch ist etwa eine einfach Erklärung, wo die declarator-ID fehlt. Eine Typ-ID wird als syntaktisches Element in einem Schablonetypargument und in einer Besetzung verwendet.

int // type-id 
int* // type-id 
int[] // type-id 
int() // type-id 
int(*)() // type-id 

Ein Template-Name ist der Name einer Vorlage. Syntaktisch erscheint es vor einer Template-Argumentliste. Das obige Zitat missbraucht "Schablonenname" und "Deklarator-ID", weil ein Schablonenname ein einfacher Bezeichner ist und keine Qualifikationsmerkmale enthält. C++ 0x um den Text zu

In Abhängigkeit Template-Deklaration, die letzte Komponente des declarator-ID soll sein, eine Template-Namen oder die Bediener-ID-Funktion (dh keine Templat-ID) geändert hat .

(Der letzte Teil erscheint in Fällen wie operator+()). Sogar der C++ 0x Text vermisst einige Fälle - siehe this defect report.

Der Missbrauch von "declator-id" passiert in der Notiz. Die Note wurde mit

von C++ 0x ersetzt

[Anmerkung: in einer Klasse Template-Deklaration, wenn der Klassenname ist ein ... - Endnote]

In Klassenvorlage Erklärungen, die Der syntaktisch angegebene Name ist ein Klassenname anstelle einer Deklarator-ID. Die Beziehung des Klassennamen und declarator-ID ist wie folgt (sehr vereinfachte ...)

class class-name { ... } declarator-id; 
class foo  { ... } bar; 

In Klassenvorlage Erklärungen gibt keine declarator-ID angegeben werden.


Eine Vorlagen-ID ist ein Vorlagenname gefolgt von einer Vorlagen-Argumentliste.


Das Zitat bedeutet, dass in einer Funktion Vorlage Erklärung muss der Name nicht ein Template-ID sein. In Ihrem Beispiel deklarieren Sie anstelle einer Vorlage eine Funktion.Es gibt jedoch immer noch Fälle, in denen eine explizite Spezialisierung eine Vorlage deklariert. Aber das kann nur für Elementfunktionsvorlagen passieren

template<typename T> 
struct A { 
    template<typename U> 
    void f(); 
}; 

// this explicit specialization *contains* a template declaration and 
// declares an identifier (a template-name) qualified by A<int>:: 
template<> template<typename U> 
void A<int>::f() { }