受this answer的启发(声称颠覆访问控制系统),我编写了以下最小版本的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{};
然后是used as
class S
{
int i;
};
template struct setptr<&S::i>;
auto no_privacy(S& s)
{
return s.*memptr<int S::*>;
}
template struct setptr<&S::i>;
为什么不违反访问控制?
访问控制被统一应用于所有名称,无论名称是从声明还是表达式引用的。
具体不包括实例化吗?在这种情况下,为什么不包含实例化?
勘误表:显式实例也被归类为声明。
答案 0 :(得分:11)
来自[temp.spec]/6(重点是我):
通常的访问检查规则不适用于显式实例化或显式专业化声明中的名称,但名称出现在函数体,默认参数,基本子句,成员中-规范,枚举器列表或静态数据成员或变量模板初始化程序。 [注:特别是,函数声明符中使用的模板参数和名称(包括参数类型,返回类型和异常规范)可能是私有类型或通常无法访问的对象。 —注 ]
因此,您看到的这项技术滥用了该规则,主要是为了允许具有私有类型或其他私有实体的类的实现模板(例如特征)的实现者