Was ist der Unterschied zwischen einer Vorlagenklasse und einer Klassenvorlage?
Antworten:
Dies ist für viele ein häufiger Verwirrungspunkt (einschließlich der Seite "Allgemeine Programmierung" auf Wikipedia, einiger C ++ - Tutorials und anderer Antworten auf dieser Seite). Für C ++ gibt es keine "Vorlagenklasse" , sondern nur eine "Klassenvorlage". Die Art und Weise, diesen Satz zu lesen, ist "eine Vorlage für eine Klasse" im Gegensatz zu einer "Funktionsvorlage", die "eine Vorlage für eine Funktion" ist. Nochmals: Klassen definieren keine Vorlagen, Vorlagen definieren Klassen (und Funktionen). Zum Beispiel ist dies eine Vorlage , nämlich eine Klasse - Vorlage , aber es ist nicht eine Klasse :
template<typename T> class MyClassTemplate
{
...
};
Die Deklaration MyClassTemplate<int> ist eine Klasse oder pedantisch eine Klasse, die auf einer Vorlage basiert. Es gibt keine besonderen Eigenschaften einer Klasse, die auf einer Vorlage basiert, im Vergleich zu einer Klasse, die nicht auf einer Vorlage basiert. Die besonderen Eigenschaften beziehen sich auf die Vorlage selbst .
Der Ausdruck "Vorlagenklasse" bedeutet nichts, da das Wort "Vorlage" für C ++ keine Bedeutung als Adjektiv hat, wenn es auf das Substantiv "Klasse" angewendet wird. Dies impliziert die Existenz einer Klasse , die eine Vorlage ist (oder definiert) , die kein in C ++ vorhandenes Konzept ist.
Ich verstehe die allgemeine Verwirrung, da sie wahrscheinlich auf der Tatsache beruht, dass die Wörter in der Reihenfolge "Vorlagenklasse" in der tatsächlichen Sprache erscheinen, was eine ganz andere Geschichte ist.
Der Unterschied besteht darin, dass der Begriff "Vorlagenklasse" im C ++ - Standard einfach nicht vorhanden ist. Es ist ein Begriff, der hauptsächlich von Leuten verwendet wird, die denken, dass der Begriff "Klassenvorlage" verwirrend ist (wie die Qt-Unternehmen Nokia und früher Trolltech).
Der Standard hat kein Konzept davon, daher liegt es an anderen Menschen, etwas zu verändern. Einige Leute verwenden es synonym, andere sagen, dass sich der Begriff "Vorlagenklasse" auf eine instanziierte oder explizit spezialisierte Klassenvorlage bezieht, was ihn dem Begriff "Spezialisierung auf Klassenvorlagen" gleichstellen würde. Historisch hatte es diese Bedeutung. Das mit Anmerkungen versehene Referenzhandbuch wird auf Seite 343 definiert
Eine aus einer Klassenvorlage generierte Klasse wird als Vorlagenklasse bezeichnet, ebenso wie eine Klasse, die speziell mit einem Vorlagenklassennamen als Namen definiert ist
Der Name der Nicht-Terminal- Vorlagenklasse entspricht der im heutigen Standard verwendeten Nicht-Terminal- Vorlagen-ID und wird nicht angezeigt template-name < arguments >.
Um Sie mit den heutigen Begriffen vertraut zu machen, ist dies wichtiger als die Verwendung zweifelhafter alter Begriffe
// (1) defines a class template
template<typename T> class A { };
// (2) defines a class template explicit specialization
template<> class A<int> { };
// (3) defines a class template partial specialization
template<typename T> class A<T*> { };
// (4) explicitly instantiates A<char>.
template class A<char>;
// (5) implicitly instantiates A<short> (because of the member declaration)
struct D { A<short> a; };
Bjarne Stroustrup, der Schöpfer von C ++, sagt in seinem Buch The C ++ Programming Language 4. Ausgabe , 23.2.1 Definieren einer Vorlage:
Es gibt Leute, die semantisch zwischen den Begriffen Klassenvorlage und Vorlagenklasse unterscheiden . Ich nicht; das wäre zu subtil: bitte halte diese Begriffe für austauschbar. Ebenso halte ich Funktionsvorlagen für austauschbar mit Vorlagenfunktionen .
Eine Vorlagenklasse bezieht sich auf das Entwurfsmuster der Vorlagenmethode , während die Klassenvorlage nur eine Klassenvorlage zum Ausfüllen der Lücken ist.
Eine Klassenvorlage ist eine Vorlage, die zum Generieren von Klassen verwendet wird, während eine Vorlagenklasse eine Klasse ist, die von einer Vorlage erstellt wird.
Vorlagenklasse: Eine Klasse mit generischer Definition oder eine Klasse mit Parametern, die erst instanziiert wird, wenn die Informationen vom Client bereitgestellt werden. Es wird auf einen Jargon für einfache Vorlagen verwiesen. Einfache Klasse mit Präfixvorlage und Verwendung von T. Klassenvorlage: Die individuelle Konstruktion einer Klasse wird durch eine Klassenvorlage angegeben, die der Art und Weise, wie einzelne Objekte mithilfe einer Klasse konstruiert werden, fast ähnlich ist. Es wird auf ein Objekt der Vorlagenklasse Ex-Klassenname Objektname (Argumentliste) verwiesen.
Die Klassenvorlage ist eine generische Klasse für verschiedene Objekttypen. Grundsätzlich bietet es eine Spezifikation zum Generieren von Klassen basierend auf Parametern. Immer wenn ein neues Objekt erstellt wird, findet zu diesem Zweck eine neue Klasse im Speicher statt. Dies wird als Instanziieren einer Klassenvorlage bezeichnet, und jede instanziierte Version der Klasse wird als Vorlagenklasse bezeichnet.
Schauen Sie sich dieses Papier an (aus wg21 und wurde 1992 veröffentlicht) :
Konsistente Terminologie
Ein Großteil der bisherigen Argumente und Meinungsverschiedenheiten bezog sich auf die Terminologie, die in dem Kapitel zur Beschreibung von Vorlagen verwendet wurde. Am häufigsten war die unterschiedliche Anwendung von 'Funktionsvorlage' und 'Vorlagenfunktion' , um unterschiedliche Ideen und Absichten auszudrücken. Da keine einheitliche Benennung angewendet wird, führt dies zu Verwirrung und Argumentation.
Für die Zwecke dieses Dokuments als Vorschlag zur formellen Annahme durch den Ausschuss in Diskussionen über Vorlagen und zum Zwecke der Klarstellung der Dokumentation; Ich schlage vor, dass wir die Formalisierung übernehmen, dass eine nachfolgende '-Vorlage' eine Reihe von Typen oder Funktionen beschreibt, die von einer Vorlage beschrieben werden. Und dass eine führende ' Vorlage-' verwendet wird, um die Vorlagendefinition eines Teils einer 'Vorlage' zu beschreiben , wie z
'template-member-function'. Also: -
- 'Funktionsvorlage': Eine Reihe von Funktionen, die von einer Vorlage beschrieben werden und für einige Typinformationen parametrisch sind, die als Argument für diese Vorlage bereitgestellt werden. Zum Beispiel :-
template<class T> int nullcheck( T* pT )
{ return ( pT != 0 ); }
- 'Klassenvorlage': Eine Reihe von Klassen, die von einer Vorlage beschrieben werden und für einige Typinformationen parametrisch sind, die als Argument für diese Vorlage bereitgestellt werden. Zum Beispiel :-
template<class T> class S {
int i;
public:
int sep_member();
int imm_member()
{ return 2; }
}
- 'Template-Funktion': Dieser Begriff ist nicht mehr erlaubt. **
'template-class': Dieser Begriff ist nicht zulässig. **
'member-function-template': Dieser Begriff ist nicht zulässig, da er eine Eigenschaft beschreibt, die derzeit von der Vorlagendefinition nicht unterstützt wird. Unter Verwendung der obigen Terminologiekonvention würde dies ein Mitglied einer Nichtklassenvorlage beschreiben, deren Definition selbst eine Vorlage war. Zum Beispiel :-
class Normal { public:
template<class T> int foo(T*pT)
{ return ( pT == 0 ); }
};
Da Vorlagen derzeit jedoch auf den globalen Bereich beschränkt sind, ist eine solche Vorlage ungültig.
- 'template-static-member-function':
- 'template-member-function':
- 'template-static-member':
- 'template-static-data-member ' template-member ': Alternative Begriffe für die Definition eines Mitglieds, das getrennt von der' Klassenvorlage 'angezeigt wird, zu der es gehört. Zum Beispiel :-
template<class T> int S<T>::sep_member()
{ return i; }
NormalKlasse, die Sie oben beschrieben haben: Mir war nicht bewusst, dass eine solche Member-Function-Vorlage verboten war. Es wird von allen Compilern akzeptiert, die ich ausprobiert habe. Was vermisse ich?