Die Regel, die GCC erzwingen soll, ist in [basic.scope.class]:
2) Ein Name N, der in einer Klasse S verwendet wird, muss sich auf dieselbe Deklaration in seinem Kontext beziehen und wenn er im abgeschlossenen Bereich von S neu bewertet wird. Für einen Verstoß gegen diese Regel ist keine Diagnose erforderlich.
Der Standard besagt, dass die Verletzung keine Diagnose erfordert, daher ist es möglich, dass sowohl GCC als auch Clang konform sind, weil (wenn GCC richtig ist) der Code nicht gültig ist, aber der Compiler sie nicht diagnostizieren muss / p>
Der Zweck dieser Regel besteht darin, dass Namen, die in einer Klasse verwendet werden, immer dieselbe Bedeutung haben, und das Neuordnen von Elementen ändert nicht die Art, wie sie interpretiert werden, z. B.
%Vor%In diesem Beispiel ändert sich der Name %code% und die Reihenfolge der Mitglieder ändert die Größe von %code% . Wenn %code% definiert ist %code% bezieht sich auf den Typ %code% , aber im abgeschlossenen Bereich von %code% bezieht es sich stattdessen auf %code% . Dies verstößt gegen die oben genannte Regel.
In Ihrem Beispiel ändert sich der Name %code% viel weniger gefährlich, da er sich immer noch auf den gleichen Typ bezieht, jedoch ändert er sich von der Deklaration von %code% zur Deklaration von %code% . Die Regel ist so formuliert, dass sie sich auf Erklärungen bezieht, daher denke ich, dass der GCC richtig ist.
Ich möchte, dass eine Struktur einen Typalias in einen anderen Typ für Metaprogrammierungszwecke enthält:
%Vor%Dann kann ich Sachen wie %code% in einer Vorlage usw. machen.
Wie ich verstehe, ist dieser Typ-Alias gültig, weil er die Bedeutung des Typs %code% nicht ändert. Clang kompiliert das glücklich.
Der GCC beschwert sich jedoch:
%Vor%Jetzt bin ich verwirrt, weil ich die Bedeutung von %code% von %code% explizit nicht ändere.
Was ist das richtige Verhalten für C ++ 14? Ich weiß, dass ich das umgehen kann, indem ich die %code% umbenenne, aber ich würde gerne verstehen, ob der Fehler von GCC hier richtig ist.
Anmerkungen:
Getestet mit clang ++ 3.8 und gcc 5.4, aber Godbolt schlägt vor, dass dies in neueren GCC-Versionen nicht geändert wurde .
Ich schaute auf Interaktion zwischen declltype und Klassenmitgliedsnamen shadowing einen externen Namen , wo der Name eines variable kann sich entweder auf eine Variable im äußeren Bereich oder auf einen Klassenmember beziehen. Im Gegensatz dazu handelt meine Frage hier von einem Typalias. Es gibt keine Mehrdeutigkeit, da sich %code% immer auf %code% innerhalb des Klassenbereichs bezieht. Ich sehe nicht, wie die Antwort dort auf mein Problem zutrifft.
Dies liegt wahrscheinlich an einem Missverständnis dessen, welcher Typ tatsächlich Aliasnamen sind.