在好友声明中使用限定名称的规则是什么?
What are the rules for using qualified names in friend declarations?
以下代码产生编译错误(至少在最新版本的 gcc 上):
namespace a {
class X { friend void ::foo(); };
}
错误是:
'void foo()' should have been declared inside '::'
如果我们从声明中删除::
,根据标准,foo
将被引入命名空间a
(尽管它不可见)。不需要在a
内部预先声明 foo。
我的问题是,鉴于上述情况,为什么在全局命名空间中预先声明是一项要求?为什么名称foo
不成为全局命名空间的成员?我在标准中也找不到任何明确禁止的段落,所以我很想知道。
您要
查找的段落是[dcl.meaning](C++11中的8.3(1)):
(...声明符 id 不得限定,除非定义其类之外的成员函数或静态数据成员,在其命名空间之外定义或显式实例化命名空间的函数或变量,或定义其命名空间之外的显式专用化,或者声明作为另一个类或命名空间成员的友元函数。当声明符 id 是限定的时,声明应引用限定符所引用的类或命名空间的先前声明的成员(或者,如果是命名空间,则引用该命名空间的内联命名空间集的元素)。
(强调我的)这意味着你不能写
namespace a { }
void a::foo() { }
除非已在命名空间中使用非限定声明符声明a::foo
。而且由于朋友没有例外,您也不能为朋友这样做。
[namespace.memdef](C++11)中的7.3.1.2(3))中的脚注更明确地提到了朋友的特殊情况:
(...如果非本地类中的友元声明首先声明一个类或函数95,则友元类或函数是最内层封闭命名空间的成员。(...)
95)这意味着类或函数的名称是不限定的。
相关文章:
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 假设声明中某些上下文中需要的名称查找规则是什么
- C++具有不同作用域的相同名称的名称解析规则
- 哪里定义了查找名称最直接声明的名称查找规则
- 函数参数绑定通过参考与传递指针传递数组的规则
- C++中名称查找和名称绑定之间的区别
- 模板功能中的名称查找规则
- MISRA C++规则 14-5-1:在与类型关联的命名空间中声明的泛型函数模板的名称
- 在字符串上迭代,但将定界器保持在子字符串中,包括其他规则
- 将规则生产绑定到我的结构成员时出现编译错误
- 在好友声明中使用限定名称的规则是什么?
- 对C++中的异常机制执行动态绑定规则
- Boost Spirit中的名称表达式,不指定规则
- Boost精灵规则与phoenix绑定到结构编译失败
- C++名称解析(和重载)规则列表
- 如何从精神语义规则绑定/调用存储在fusion::vector中的boost::函数
- 嵌套名称说明符的名称查找规则
- 什么名称查找规则适用于静态 const 数据成员定义中的名称
- 在C++中具有名称绑定的EDSL
- x / y的确切名称查找规则是什么?