c++ - The member function Outer::f() is not a friend of class Outer::Inner. Why? -


according clang, gcc , vs2013, function outer::f not friend of class outer::inner.

struct outer {     void f() {}     class inner {         friend void f();         static const int = 0;     }; };  void f() { int = outer::inner::i; } 

from [namespace.memdef]/3 expect function outer::f friend of outer::inner, instead of ::f, because friend declaration not first in namespace containing name f.

[namespace,memdef]/3 (emphasis mine):

every name first declared in namespace member of namespace. if friend declaration in non-local class first declares class, function, class template or function template97 friend member of innermost enclosing namespace. friend declaration not make name visible unqualified lookup (3.4.1) or qualified lookup (3.4.3). [ note: name of friend visible in namespace if matching declaration provided @ namespace scope (either before or after class definition granting friendship). — end note ] if friend function or function template called, name may found name lookup considers functions namespaces , classes associated types of function arguments (3.4.2). if name in friend declaration neither qualified nor template-id , declaration function or elaborated-type-specifier, lookup determine whether entity has been declared shall not consider scopes outside innermost enclosing namespace.

the first part of standard quoted says (emphasis mine):

every name first declared in namespace member of namespace. if friend declaration in nonlocal class first declares class or function the friend class or function member of innermost enclosing namespace.

you assuming class same namespace, not correct.

namespace outer {     void f();     class inner {         friend void f();         static const int = 0;     }; }  void outer::f() { int = outer::inner::i; } 

should work. use class member function friend, you'll have use:

struct outer {     void f();     class inner {         friend void outer::f();         static const int = 0;     }; };  void outer::f() { int = outer::inner::i; } 

Comments