Ich habe zufällig festgestellt, dass dieser Code kompiliert und korrekt funktioniert:
%Vor% Warum ist das korrekt ( decltype(M::M::M::M::some_int) <=> decltype(M::some_int)
)?
Für welche anderen Konstrukte kann man dieses Muster mit class::class::...::member
verwenden?
Compiler: Microsoft (R) C / C ++ Optimierungscompiler Version 19.00.23824.1 für x86
Dies funktioniert wegen injected-class-name :
(N3337) [class]/2:
Ein Klassenname wird in den Gültigkeitsbereich eingefügt, in dem er unmittelbar nach dem Anzeigen des Klassennamens deklariert wird. Der Klassenname wird ebenfalls in den Bereich der Klasse selbst eingefügt. Dies wird als der Name der injected-Klasse bezeichnet. Zum Zweck der Zugriffsprüfung wird der Name der injected-Klasse so behandelt, als wäre er ein öffentlicher Membername. [...]
Sie können diese also beliebig verschachteln und sie werden auch mit abgeleiteten Typen arbeiten:
%Vor% Beachten Sie, dass im Fall von A[::A]*::A
der Name der injected-Klasse stattdessen als Konstruktor betrachtet werden kann:
[class.qual]/2:
In einer Suche, in der der Konstruktor ein akzeptables Nachschlageergebnis ist und der Nested-Name-Specifier nominiert Eine KlasseC
:- Wenn der nach dem Nested-Name-Specifier angegebene Name bei der Suche in
C
der Name der injected-class ist vonC
(Klausel 9) oder- [...]
Der Name wird stattdessen als Konstruktor der Klasse
C
betrachtet.
Dies ist in allen Kontexten gültig, nicht nur decltype
. Eine Klasse enthält einen eigenen Namen als eingefügten Klassennamen. Also wird innerhalb einer Klasse A::B::M
der Name M
eingefügt, um auf die Klasse A::B::M
zu verweisen. Das bedeutet, dass Sie M::M::M::some_member
verwenden können, um auf Mitglieder dieser Klasse zu verweisen, wenn Sie das wirklich wollen.
Beachten Sie, dass sich die Situation leicht unterscheidet, wenn nur auf den Klassennamen selbst verwiesen wird (z. B. M::M::M
). Wenn ein solcher Verweis an einer Stelle auftritt, an der auch ein Verweis auf eine Funktion möglicherweise korrekt ist, wird stattdessen die Syntax verwendet, um auf den Konstruktor zu verweisen. In Nur-Typ-Kontexten ist jedoch auch eine solche Referenz gültig. Beispiel: