How to piss off everyone by getting around C++ access specifiers:
template <typename Tag>
struct NameableEntity {
// ADL can find this overload since it is a friend
friend auto getFriend(NameableEntity<Tag>);
};
// Instantiation of this template will define the appropriate overload of getFriend
template <typename Tag, auto PrivatePointer>
struct StealPointer {
friend auto getFriend(NameableEntity<Tag>) {
return PrivatePointer;
}
};
template <typename Tag>
auto getPointerByTag() {
return getFriend(NameableEntity<Tag>{});
}
struct X {
private:
int m;
int n;
};
// Explicit template instantations don't check access levels of members
// Exploit this to get a pointer to a private member
struct XMTag;
template struct StealPointer<XMTag, &X::m>;
struct XNTag;
template struct StealPointer<XNTag, &X::n>;
void touchSomePrivateParts(X& x) {
// Presto!
int X::* mPointer = getPointerByTag<XMTag>();
x.*mPointer = 4;
int X::* nPointer = getPointerByTag<XNTag>();
x.*nPointer = 5;
}
https://godbolt.org/z/sKPefcGzs