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.
Access Control: Take/Return Request Pending Action Specifies which user roles can take or return ownership of requests pending action. They can take ownership of requests pending action from the following options: A group queue. The queue of another user in the same business unit or child business unit.
For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.
In UML models, template parameters are formal parameters that once bound to actual values, called template arguments, make templates usable model elements. You can use template parameters to create general definitions of particular types of template.
A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.
From [temp.spec]/6 (emphasis mine):
The usual access checking rules do not apply to names in a declaration of an explicit instantiation or explicit specialization, with the exception of names appearing in a function body, default argument, base-clause, member-specification, enumerator-list, or static data member or variable template initializer. [ 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 that would normally not be accessible. — end note ]
So this technique you see abuses this rule, which is primarely there to allow implementers of a class specialize templates (such as traits) with private types or other private entities
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With