c++ - 在友元声明中使用限定名称的规则是什么?

标签 c++ namespaces friend

以下代码会产生编译错误(至少在最新版本的 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)):

(...) A declarator-id shall not be qualified except for the definition of a member function or static data member outside of its class, the definition or explicit instantiation of a function or variable of a namespace outside of its namespace, or the definition of an explicit specialization outside of its namespace, or the declaration of a friend function that is a member of another class or namespace. When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers (or, in the case of a namespace, of an element of the inline namespace set of that namespace).

(强调我的)这意味着你不能写

namespace a { }

void a::foo() { }

除非 a::foo 已在命名空间内使用非限定声明符进行声明。既然 friend 也不异常(exception),你也不能为 friend 这样做。

[namespace.memdef](C++11 中的 7.3.1.2 (3))中的脚注针对 friend 的特殊情况更明确地提到了这一点:

(...) If a friend declaration in a non-local class first declares a class or function95 the friend class or function is a member of the innermost enclosing namespace. (...)

95) This implies that the name of the class or function is unqualified.

关于c++ - 在友元声明中使用限定名称的规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27974521/

相关文章:

Django CMS apphook 命名空间

c++ - 如何为具有相同模板的模板类定义和使用友元函数?

namespaces - 在 Rust 中声明多个 "use"语句是否被认为是不好的风格?

python - 使用字典访问 Python 中类的嵌套实例

c++ - 自动填写表格并运行程序

c++ - C++ 中的外部枚举

c++ - 从 friend 类访问私有(private)变量 - 我相信我的语法是错误的

c++ - 使用友元类减少编译时间和依赖性

c++ - 在 C++ 中使用非虚拟公共(public)接口(interface)和作用域锁避免死锁

c++ - 我怎样才能从文件中提取文件属性/元数据/注释