user621819
user621819

Reputation:

Injection of a friend declaration into a namespace, Eckel, Vol1, pg:440?

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

Answers (2)

user396672
user396672

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

Ilya Lavrenov
Ilya Lavrenov

Reputation: 367

you must write

y.func(&zx, 30); // work well

with y. Because fund - its a class instance method

Upvotes: 1

Related Questions