Type alias with same name as type

GCC and Visual C++ are correct.

Indeed you can use using to in effect change the access of a member, e.g.

using Inner_ = Inner;

with

static_assert(std::is_pod<Test::Inner_>::value, "");

in the function.

But in the case where the type alias has the same name as the member, C++ requires that the scope resolution operator looks up the member. So in your case Test::Inner refers to the actual member rather than to the using and compilation should therefore fail as it's private.


See https://en.cppreference.com/w/cpp/language/qualified_lookup, and in particular

Qualified lookup within the scope of a namespace N first considers all declarations that are located in N and all declarations that are located in the inline namespace members of N (and, transitively, in their inline namespace members). If there are no declarations in that set then it considers declarations in all namespaces named by using-directives found in N and in all transitive inline namespace members of N