为什么显式模板实例化存在访问检查漏洞
Why does a hole for access checking exist for explicit template instantiations?
〔temp.explicit〕包含以下语句:
通常的访问检查规则不适用于用于指定显式实例化的名称[注:In特别是在函数声明符中使用的模板参数和名称(包括参数类型,返回类型和异常规范(可能是私有类型或对象,而通常不会可访问,并且该模板可能是成员模板或成员函数,而通常不会可访问--尾注]
为什么这些规则是专门针对这种情况禁用的?在极端情况下,这允许以定义良好的方式任意访问任何类的任何私人成员(演示-零警告(:
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已经在上面的评论中解释了其中的大部分
相关文章:
- 我们可以访问一个不存在的联盟的成员吗
- CPP 使用不存在的键访问映射
- 如果键不存在,使用 [] 运算符访问 STL Map 元素会添加新元素
- 存在内存访问异常,但我不确定我的代码中出了什么问题
- Boost文件系统存在访问违规
- 自 C++17 以来,复制 elision 不需要存在和访问复制或移动 CTOR
- 就SFINAE而言,访问不存在的成员不被视为"error"吗?
- 访问结构C++中存在的位集
- 如果只存在私有函数,则访问基类中的私有数据类型
- 我的代码中存在死锁/访问冲突,即使我已经相互排除了它
- SQLite。C++Builder 6 CodeGuard 中的 sqlite3.c 中存在大量"访问溢出算法 overrunresource 泄漏"
- 类成员突然变得不可访问/不存在
- 如何确保向量中访问的索引存在
- 从派生 * 到基 * 的转换存在,但无法访问
- VS2008 中存在访问冲突,但在 VS2002 中没有
- 仅在调试时std::string析构函数中存在访问冲突
- 如果全局中存在相同的变量,如何访问匿名命名空间变量
- 运算符重载实现:0xC0000005:读取位置存在访问冲突
- 为什么显式模板实例化存在访问检查漏洞
- 双链接列表中存在访问冲突