I want a struct to contain a type alias to another type for metaprogramming purposes:
struct Foo {};
struct WithNestedTypeAlias {
using Foo = Foo;
};
The rule GCC is enforcing is in [basic.scope.class]:
2) A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.
The standard says violating this doesn't require a diagnostic, so it's possible that both GCC and Clang are conforming, because (if GCC is right) the code is not valid, but the compiler is not required to diagnose it.
The purpose of this rule is so that names used in a class always mean the same thing, and re-ordering members doesn't alter how they are interpreted e.g.
struct N { };
struct S {
int array[sizeof(N)];
struct N { char buf[100]; };
};
In this example the name N
changes meaning, and reordering the members would change the size of S::array
. When S::array
is defined N
refers to the type ::N
but in the completed scope of S
it refers to S::N
instead. This violates the rule quoted above.
In your example the name Foo
changes in a far less dangerous way, because it still refers to the same type, however strictly speaking it does change from referring to the declaration of ::Foo
to the declaration of S::Foo
. The rule is phrased in terms of referring to declarations, so I think GCC is right.