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<A_f, &A::a>;
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.
Yes, it's legal. The relevant text is at §14.7.2/12, talking about explicit template instantiation:
12 The usual access checking rules do not apply to names used to specify explicit instantiations. [ Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible. — end note ]
Emhpasis mine.