So, always thought that it's impossible without undefined behavior to access private members of arbitrary classes without being friend.
Today I noticed I've been horribly wrong, after reading some insightful commit to the clang compiler, that enabled it to allow explicit instantiation to disregard accessibilities, as per the Standard. This enables us to access private members of others. As an experiment, I created some class templates
template<typename Tag> struct result { /* export it ... */ typedef typename Tag::type type; static type ptr; }; template<typename Tag> typename result<Tag>::type result<Tag>::ptr; template<typename Tag, typename Tag::type p> struct rob : result<Tag> { /* fill it ... */ struct filler { filler() { result<Tag>::ptr = p; } }; static filler filler_obj; }; template<typename Tag, typename Tag::type p> typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;
So, how is it used? Let's have an example
struct A { private: void f() { std::cout << "proof!" << std::endl; } }; struct Af { typedef void(A::*type)(); }; template class rob<Af, &A::f>;
Ah, that's all to expose poor A's "f" member. Now anyone can use them using the member pointer snytax, as does the main function below
int main() { A a; (a.*result<Af>::ptr)(); }
Of course, as Herb Sutter told us, don't do these things in real code.