Reputation:
I'm trying to understand injection of a friend declaration into a namespace:
#include <iostream>
using namespace std;
namespace Z { //forward declaration
class X;
}
class Y {
public:
void func(Z::X*, int);
};
namespace Z {
class X {
int i;
public:
X() : i(999) {}
friend void Y::func(Z::X*, int);
void print(void) { cout << i << endl; }
};
}
void Y::func(Z::X* ptr, int i)
{
ptr->i = 40;
}
int main(void)
{
Z::X zx;
zx.print();
Y y;
y.func(&zx, 40);
zx.print();
using namespace Z;
// func(&zx, 30); DOES NOT WORK
}
friendInject.cc:39: error: 'func' was not declared in this scope The book says: "You can inject a friend declaration into a namespace by declaring it within an enclosed class". "Now the function you() is a member of the namespace Me."
What exactly does this mean?? I tried Y::func but that perhaps works only for static member functions??
Upvotes: 3
Views: 1262
Reputation: 3166
C++11 Standard 7.3.1.2 (3) says:
"If a friend declaration in a nonlocal class first declares a class or function [footnote: this implies that the name of the class or function is unqualified] the friend class or function is a member of the innermost enclosing namespace."
So any unqualified friend function declaration introduces a free function in the innermost enclosing namespace; (probably) the book referes to this as to "injection into namespace".
Note that it is even possible to define (implement) a function inside friend declaration:
namespace Z
{
class C
{
friend void f(void){/*do something*/}
};
}
This friend declaration not only "injects" but also implements free function f in the namespace Z (f is not a member of class C itself!), so no other declarations or definitions are needed for Z::f.
As to your example,
friend void Y::func(Z::X*, int);
is qualified (prefixed with namespace/class name), so it doesn't declare a function, it only refers to a member function Y::func previously declared in class Y. Such friend declarations "injects" nothing.
Upvotes: 0
Reputation: 367
you must write
y.func(&zx, 30); // work well
with y. Because fund - its a class instance method
Upvotes: 1