模板 ID 中的好友查找异常
Friend lookup exception from template-id?
请考虑 [namespace.memdef]/3 中的以下子句:
如果
friend
声明中的名称既不是 限定也不是模板 ID 并且声明是一个函数或详细类型说明符,确定实体是否已事先声明的查找不应考虑最内层之外的任何范围 封闭命名空间。
模板 ID 和限定名称的异常是否有原因?就此而言,是否有理由将查找不是模板 ID 的非限定名称限制在最里面的封闭命名空间?此子句是否解决特定问题或用例?
为什么限制不适用于限定名称和模板 ID?
限定名称和模板 ID 不能将新成员引入封闭命名空间,这就是 [namespace.memdef]p3 中的注释试图说的:
[ 注意:其他形式的
friend
声明不能声明新的 最里面封闭命名空间的成员,因此遵循通常 查找规则。— 尾注 ]
因此,对于限定名称和模板 ID,不需要此类限制。
请注意,模板 ID 缺少模板参数的声明,限定 ID 可能会将名称引入遥远的、不相关的命名空间。
为什么会有限制?
这部分答案还不完整,但代表了"研究"的现状。请随时做出贡献。
由于N0783 - 命名空间问题和建议的决议"试图澄清当前未定义或未完全指定的许多命名空间问题",引入了该限制(可能?(。
1995年的这份文件载有关于通过友元声明引入的实体声明相关问题的两次启发性讨论。请记住,当时的名称查找规则是不同的:
- 尚未引入依赖于参数的查找(*(
- 根据当前规则,通过友元声明引入的名称无法通过纯非限定查找(无 ADL(找到,请参阅 [namespace.memdef]p3 和 CWG 1477。N0878 中的示例表明,当时可以通过纯非限定查找找到这些名称。
(*( 我能找到的最好的是 1996 年 3 月的 N0878,上面写着">最近对工作文件进行了更改,以添加"Koenig 查找规则">
首先,N0783 中的函数示例:
void f(char); namespace A { class B { friend void f(char); // ::f(char) is a friend friend void f(int); // A::f(int) is a friend void bf(); }; void B::bf() { f(1); // calls A::f(int); f('x'); // also calls A::f(int) because ::f is hidden } }
第二个友元声明必须引入一个新函数。N0783 尝试指定在哪个范围内引入此声明。它建议
给定名称的所有友元声明必须在一个中声明实体 特定范围。
作为一般规则,以避免上述情况的意外。
所以问题是,他们在哪个范围内声明实体?有 两种可能性,要么
- 查找函数的先前声明时,请查找直到到达最近的封闭命名空间,或者
- 查找以前的声明时,请在所有封闭作用域中查找已声明的函数的名称。如果上一个 找到名称的使用,声明将注入该范围。 如果没有找到以前使用该名称,则朋友将被注入 最近的封闭命名空间范围。
规则 #2 意味着任何调用的函数的存在
f
封闭范围(无论类型是否匹配(都足以 使友元声明注入该范围。我认为规则#2显然是不可接受的。好友声明 在命名空间中将受到该命名空间的任何全局声明的影响 名字。考虑一下这对操作员功能意味着什么!这 在全球范围内存在任何
operator+
功能将强制 所有朋友operator+
运营商也出现在全球范围内! 在全局范围内存在模板将具有相同的 影响。
对于类类型:
namespace N { class A { void f(); }; } using namespace N; namespace M { class B { friend class A; // Without this rule // makes N::A a friend B(); }; class A { void f(); }; } void N::A::f() { M::B b; } // A friend under current rules void M::A::f() { M::B b; } // A friend under proposed rules
根据现行规则,这两个示例都不那么有趣,因为通过好友声明引入的名称只能通过 ADL 找到。这种限制可能是历史文物。在引入ADL之后,需要更多的"研究"来跟踪这一限制的发展。
- 正在查找文档以获得PS4平台的C++中的设备信息
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 在C++中查找文件
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 模板元程序查找相似的连续类型名称
- 在UNIX系统中使用DIR查找文件的字节大小
- 查找最接近的大于当前数字的数字的索引
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 查找后更改类变量
- 使用正则表达式regex_search在字符串中查找字符串
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 使用用户定义的函数查找完美数时出现浮点异常错误
- 如何在 VS C++ 中查找发生异常的位置
- 查找哪个函数在 VC++6 中引发异常
- 查找交集时出现浮点异常
- std::string异常以及如何查找已编译的c++应用程序的平台工具集
- 模板 ID 中的好友查找异常