Inspired from this answer, which claims to subvert the access control system, I wrote the following minimal version of the hack
template<typename T>
inline T memptr{};
template<auto Val>
struct setptr
{
struct setter { setter() { memptr<decltype(Val)> = Val; } };
static setter s;
};
template<auto Val>
typename setptr<Val>::setter setptr<Val>::s{};
which is then used as
class S
{
int i;
};
template struct setptr<&S::i>;
auto no_privacy(S& s)
{
return s.*memptr<int S::*>;
}
Why doesn't template struct setptr<&S::i>;
violate access control?
Is it because [class.access]
Access control is applied uniformly to all names, whether the names are referred to from declarations or expressions.
specifically doesn't include instantiations? In which case, why doesn't it include instantiations?
Errata: Explicit instantiations are also classified as declarations.