Das typename-Schlüsselwort in C++
- Qualifizierte und nicht qualifizierte Namen in C++
- Abhängige und nicht abhängige Namen in C++
-
Verwenden des Schlüsselworts
typename
in C++
Dieser Artikel behandelt das Schlüsselwort typename
in C++.
Um die Bedeutung des Schlüsselworts typename
zu verstehen, müssen wir die Schlüsselkonzepte von qualifizierten
und abhängigen
Namen verstehen.
Qualifizierte und nicht qualifizierte Namen in C++
Ein qualifizierter Name gibt einen Bereich an. Sehen wir uns ein Beispiel an, um es besser zu verstehen.
#include <bits/stdc++.h>
int main() { std::cout << "Hello world!" << std::endl; }
Die Verweise auf cout
und endl
sind hier qualifizierte Namen. Aber wenn wir beide mit einer using
-Deklaration in den Geltungsbereich bringen, d.h. using namespace std
und nur cout
allein verwenden, würden sie zu unqualifizierten
Namen, weil ihnen das std::
fehlt.
Abhängige und nicht abhängige Namen in C++
Abhängige Namen sind die Namen, die von einem Vorlagen
-Parameter abhängen.
Schauen wir uns einen Beispielcode an, um ihn besser zu verstehen.
template <class T>
class MyClass {
int i;
vector<int> vi;
vector<int>::iterator vitr;
T t;
vector<T> vt;
vector<T>::iterator viter;
}
Die ersten drei Deklarationen werden als nicht abhängige Namen bezeichnet, da ihr Typ zum Zeitpunkt der Vorlagendeklaration bekannt ist.
Wenn wir uns dagegen den zweiten Satz von Deklarationen ansehen, sind T
, vector<T>
und vector<T>::iterator
abhängige Namen, da ihr Typ bis zum Zeitpunkt der Instanziierung nicht bekannt ist, da sie von ihnen abhängen den Template-Parameter T
.
Verwenden des Schlüsselworts typename
in C++
Als allgemeine Regel gilt, dass das Schlüsselwort typename
zwingend vor einem qualifizierten oder abhängigen Namen verwendet werden muss, der sich auf einen Typ bezieht.
Daher wird das Schlüsselwort typename
eingeführt, um anzugeben, dass der folgende Bezeichner ein Typ und keine statische Mitgliedsvariable ist.
class A {
public:
typedef int myPtr;
};
template <class T>
class myClass {
public:
typename T::SubType* myPtr;
}
Im obigen Code teilt das Schlüsselwort typename
dem Compiler mit, dass SubType
ein Typ der Klasse T
ist, was bedeutet, dass der Zeiger myptr
ein Typ von T::SubType
ist.
Ohne das Schlüsselwort typename
wird SubType
als statisches Element betrachtet und vom Compiler als Multiplikation von SubType
vom Typ T
mit dem Zeiger myptr
ausgewertet.
T::SubType * myptr //compiler will think it's multiplication
Wenn wir das Schlüsselwort typename
im obigen Code nicht verwenden, führt dies zu einem Kompilierungsfehler, da der Compiler nicht weiß, ob T::SubType
auf einen typenamen oder ein statisches Mitglied von verweist T
.