Human conversation
I'll start by describing what is happening here. Forgive me if you already know this, but it creates the necessary context for subsequent actions.
The compiler permits unqualified A to ::C::A (the result will be the same if you make the change yourself at the source level). Since ::C::A not available, an error message is displayed.
You suggest that the compiler detect that ::C::A unavailable, and a reference to A should be considered a reference to ::A as a reserve. However ::C::A and ::A can easily be two completely different.
Automatic guessing of what should be done here is not only subject to errors and / or hair extension , but also completely contrary to the spirit of C ++.
Standardese
Confirmation that this behavior is consistent and in design, directly from the C ++ 11 standard.
Section 9/2 states:
The class name is inserted into the area in which it is declared immediately after viewing the class name. The class name is also inserted in the scope of the class itself; this is known as the injected class name.
This means that inside the scope of the class, C A is the name of the introduced class.
In ยง3.4 / 3, it is stated that the name of the introduced class is a candidate for searching for names:
The introduced class-class is also considered a member of this class for name-concealment and search purposes.
In ยง 3.4 / 1, it is explained that the inaccessibility of the base A does not preclude the consideration of the nested class A :
Access rules are only considered after a search and the name function overload resolution (if applicable) is satisfied.
ยง11.1 / 5 gives a direct explanation of the specific situation:
[Note: in a derived class, searching for the name of the base class will find the name of the entered class instead of the name of the base class in the area in which it was declared. The name of the entered class may be less accessible than the name of the base class in the scope in which it was declared. -end note]
The standard also gives this example, which is equivalent to yours:
class A { }; class B : private A { }; class C : public B { A *p;
ยน Imagine what happens if A initially a public base and then becomes private during refactoring. Also imagine that ::A and ::C::A not related. You expect a call like a->foo() (which was used to work) to fail because foo no longer available, but instead type A has changed behind you, and now you get "there is no method foo ". BUT?!? And this, of course, is far from the worst that could happen.