Our infamous litb has an interesting article on how to circumvent the access check.
It is fully demonstrated by this simple code:
#include
The code is clearly illegal (and requires a compile time diagnostic). In the line:
template struct Rob;
the expression A::a accesses a private member of A.
The standard is very clear about this: “Access control is applied
uniformly to all names, whether the names are referred to from
declarations or expressions.“ (§11/4, emphasis added). Since a is a private name in A, any reference to it outside of A is illegal.