Class friend functions inside namespace

I have two questions about this code below:

namespace A { class window; } void f(A::window); namespace A { class window { private: int a; friend void ::f(window); }; } void f(A::window rhs) { std::cout << rhs.a << std::endl; } 

1) why do I need the f member function inside the window class to be global, making :: f (window)?

2) why do I need to provide a function f (A :: window) in this particular case, whereas when a class is not defined inside a namespace, it is normal for a function to be declared after the function is declared by a friend.

+6
source share
3 answers

When you declare f() as a friend, it actually does in the enclosing namespace of the containing class ( A in this case) if the forwarding declaration is not already present.

So this is ...

 namespace A { class window { private: friend void ::f(window); }; } 

essentially becomes this ...

 namespace A { class window; void f(window); class window { private: friend void f(window); }; } 

Edit: Here is a snippet from the C ++ standard that explains this scenario:

Standard 7.3.1.2/3:

Each name declared in a namespace is a member of this namespace. If a friend declaration in a non-local class first declares a class or function, the friend's class or function is a member of the innermost enclosing namespace. The friend’s name was not found by an unqualified search (3.4.1) or by a qualified search (3.4.3) until a corresponding announcement is displayed in this area of ​​the namespace (before or after the definition of the class that gives friendship).

+4
source

As for 1), your function is not in the namespace, so you should use :: to tell the compiler to search outside the namespace.

Otherwise, it will look for a function inside the namespace (that they exist). Koenig search does not apply here because the window class is inside the namespace.

not too sure of 2) though, but I'm sure this is due to 1).

+3
source

1) because the function f declared and defined outside the current namespace. If you have moved the definition of your class to the same namespace as a function, whether global or otherwise you do not need to.

2) you always need to declare a function before its reference. Your class refers to a function with a friend expression.

+1
source

Source: https://habr.com/ru/post/917548/


All Articles