VS2015 和 clang 编译此代码,但 g++ 拒绝它。哪一个是正确的?
VS2015 and clang compile this code, but g++ rejects it. Which one is correct?
VS2015
和 clang
编译此代码,但 g++
rejects it.
namespace A {
struct B {
friend void f();
};
}
void A::f() {}
int main(){
}
我认为 g++ 是正确的,因为 7.3.1.2/3 中的注释:
If a friend declaration in a non-local class first declares a class,
function, class template or function template97 the friend is a member
of the innermost enclosing namespace. The friend declaration does not
by itself make the name visible to unqualified lookup
([basic.lookup.unqual]) or qualified lookup ([basic.lookup.qual]).
[ Note: The name of the friend will be visible in its namespace if a
matching declaration is provided at namespace scope (either before or
after the class definition granting friendship). — end note ] If a
friend function or function template is called, its name may be found
by the name lookup that considers functions from namespaces and
classes associated with the types of the function arguments
([basic.lookup.argdep]). If the name in a friend declaration is
neither qualified nor a template-id and the declaration is a function
or an elaborated-type-specifier, the lookup to determine whether the
entity has been previously declared shall not consider any scopes
outside the innermost enclosing namespace. [ Note: The other forms of
friend declarations cannot declare a new member of the innermost
enclosing namespace and thus follow the usual lookup rules. — end
note ]
你引用的这一部分比你强调的注释更明确:
The friend declaration does not by itself make the name visible to unqualified lookup ([basic.lookup.unqual]) or qualified lookup ([basic.lookup.qual]).
您的定义依赖于限定查找来查找已在命名空间内声明的函数。但该名称对合格查找不可见。此代码应被拒绝。
这是第 8.3 节中的相关规则 [dcl.meaning]
:
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) or to a specialization thereof; the member shall not merely have been introduced by a using-declaration in the scope of the class or namespace nominated by the nested-name-specifier of the declarator-id .
VS2015
和 clang
编译此代码,但 g++
rejects it.
namespace A {
struct B {
friend void f();
};
}
void A::f() {}
int main(){
}
我认为 g++ 是正确的,因为 7.3.1.2/3 中的注释:
If a friend declaration in a non-local class first declares a class, function, class template or function template97 the friend is a member of the innermost enclosing namespace. The friend declaration does not by itself make the name visible to unqualified lookup ([basic.lookup.unqual]) or qualified lookup ([basic.lookup.qual]). [ Note: The name of the friend will be visible in its namespace if a matching declaration is provided at namespace scope (either before or after the class definition granting friendship). — end note ] If a friend function or function template is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments ([basic.lookup.argdep]). If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace. [ Note: The other forms of friend declarations cannot declare a new member of the innermost enclosing namespace and thus follow the usual lookup rules. — end note ]
你引用的这一部分比你强调的注释更明确:
The friend declaration does not by itself make the name visible to unqualified lookup ([basic.lookup.unqual]) or qualified lookup ([basic.lookup.qual]).
您的定义依赖于限定查找来查找已在命名空间内声明的函数。但该名称对合格查找不可见。此代码应被拒绝。
这是第 8.3 节中的相关规则 [dcl.meaning]
:
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) or to a specialization thereof; the member shall not merely have been introduced by a using-declaration in the scope of the class or namespace nominated by the nested-name-specifier of the declarator-id .