I will add to Jesse's answer about the seemingly peculiar behavior of GCC in compiling:
typedef A<T> A;
vs
typedef ::A<T> A;
This also applies to using statements as well of the form:
using A = A<T>;
using A = ::A<T>;
What seems to be happening within GCC, is that during the compilation of the typedef/using statement declaring B::A, that the symbol B::A becomes a valid candidate within the using statement itself. I.e. when saying using A = A<T>;
or typedef A<T> A;
GCC considers both ::A
and B::A
valid candidates for A<T>
.
This seems odd behavior because as your question implies, you don't expect the new alias A to become a valid candidate within the typedef itself, but as Jesse's answer also says, anything declared within a class becomes visible to everything else inside the class - and in this case apparently even the declaration itself. This type of behavior may be implemented this way to permit recursive type definitions.
The solution as you found is to specify for GCC precisely which A you're referring to within the typedef and then it no longer complains.