Access control in template parameters

亡梦爱人 提交于 2020-12-27 08:55:01

问题


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.


回答1:


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



来源:https://stackoverflow.com/questions/54909496/access-control-in-template-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!