Es gibt eine Verwendung, die in C ++ noch nicht erwähnt wurde und die nicht darin besteht, auf das eigene Objekt zu verweisen oder ein Mitglied von einer empfangenen Variablen zu unterscheiden.
Sie können this
einen nicht abhängigen Namen in einen argumentabhängigen Namen innerhalb von Vorlagenklassen konvertieren, die von anderen Vorlagen erben.
template <typename T>
struct base {
void f() {}
};
template <typename T>
struct derived : public base<T>
{
void test() {
//f(); // [1] error
base<T>::f(); // quite verbose if there is more than one argument, but valid
this->f(); // f is now an argument dependent symbol
}
}
Vorlagen werden mit einem Zwei-Pass-Mechanismus kompiliert. Während des ersten Durchlaufs werden nur nicht argumentabhängige Namen aufgelöst und überprüft, während abhängige Namen nur auf Kohärenz überprüft werden, ohne die Vorlagenargumente tatsächlich zu ersetzen.
In diesem Schritt hat der Compiler, ohne den Typ tatsächlich zu ersetzen, fast keine Informationen darüber, was sein base<T>
könnte (beachten Sie, dass die Spezialisierung der Basisvorlage sie in völlig andere Typen verwandeln kann, sogar in undefinierte Typen), sodass er lediglich davon ausgeht, dass es sich um einen Typ handelt . Zu diesem Zeitpunkt ist der nicht abhängige Aufruf f
, der dem Programmierer nur natürlich erscheint, ein Symbol, das der Compiler als Mitglied derived
oder in eingeschlossenen Namespaces finden muss - was im Beispiel nicht vorkommt - und er wird sich beschweren.
Die Lösung besteht darin, den nicht abhängigen Namen f
in einen abhängigen Namen umzuwandeln. Dies kann auf verschiedene Arten geschehen, indem der Typ, in dem es implementiert ist, explizit angegeben wird (- Durch base<T>::f
Hinzufügen von base<T>
wird das Symbol abhängig, T
und der Compiler geht nur davon aus, dass es vorhanden ist, und verschiebt die eigentliche Prüfung für den zweiten Durchgang danach Argumentersetzung.
Der zweite Weg, viel sortierter, wenn Sie von Vorlagen erben, die mehr als ein Argument oder lange Namen haben, ist das Hinzufügen eines this->
vor dem Symbol. Da die von Ihnen implementierte Vorlagenklasse von einem Argument abhängt (von dem sie erbt base<T>
), this->
ist sie argumentabhängig, und wir erhalten das gleiche Ergebnis: this->f
Wird in der zweiten Runde nach dem Ersetzen der Vorlagenparameter überprüft.
this
. Bitte folgen Sie diesem Link ... ;-)