[temp.explicit]包含这样的措辞:
通常的访问检查规则不适用于用于指定显式实例化的名称.[注意:特别是,函数声明符中使用的模板参数和名称(包括参数类型,返回类型和异常规范)可能是通常不可访问的私有类型或对象,模板可能是成员模板或成员函数通常无法访问. - 尾注]
为什么这些规则专门针对此案例禁用?在极端情况下,这允许以明确定义的方式任意访问任何类的任何私有成员(演示 - 零警告):
Run Code Online (Sandbox Code Playgroud)struct A { private: int member; }; template<typename Tag, typename Tag::type M> struct Rob { friend typename Tag::type get(Tag) { return M; } }; // tag used to access A::member struct A_member { typedef int A::*type; friend type get(A_member); }; template struct Rob<A_member, &A::member>; int main() { A a; a.*get(A_member()) = 42; // write 42 to it std::cout << "proof: " << a.*get(A_member()) << std::endl; }
这就是这条规则的缺点.有什么好处?为什么我们需要这个洞来避免访问检查?
Herb Sutter 的GotW #76涵盖了这个问题。成员函数应该能够访问类的私有成员。当成员函数是模板时,您希望能够专门化这样的模板。这是 C++ 访问控制模型和模板模型之间的冲突,可以通过使 C++ 标准复杂化(已经很复杂)来避免。虽然可以通过这种方式绕过 C++ 访问控制并访问私有成员,但强烈建议您不要这样做。
注意:@Xeo 已经在上面的评论中解释了其中大部分观点。
| 归档时间: |
|
| 查看次数: |
225 次 |
| 最近记录: |