在友元声明中使用限定名称的规则是什么?
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)):
(...) 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
已经在命名空间内用不合格的声明符声明。朋友也不例外,朋友也不行。
[namespace.memdef] 中的脚注(C++11 中的 7.3.1.2 (3))更明确地提到了 friends 的特殊情况:
(...) 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.
以下代码产生编译错误(至少在最新版本的 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
已经在命名空间内用不合格的声明符声明。朋友也不例外,朋友也不行。
[namespace.memdef] 中的脚注(C++11 中的 7.3.1.2 (3))更明确地提到了 friends 的特殊情况:
(...) 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.