18

For the following snippet:

class A{
    friend void f(){};
    public:
        A(){f();} //error
};

class B{
    friend void f(void* ptr){};
    public:
        B(){f(this);} //no error
};

According to the rule that although friend functions can be defined inside a class, yet they are not visible until they are declared somewhere outside the class scope, the error in the definition of class A is explained.
But I am confused why the snippet for class B doesn't produce the same error as class A's.

Please can anyone tell me about this?

AeroX
  • 3,387
  • 2
  • 25
  • 39
Eddie Deng
  • 1,399
  • 1
  • 18
  • 30

1 Answers1

16

"Not visible" is a bit of an over-simplification. With only an in-class definition, a friend function can't be found by qualified or unqualified lookup, which is why the first snippet fails.

However, it can be found by argument-dependent lookup (ADL), so you can call it with an argument involving a type that's scoped in the same namespace as the function.

In this case, the argument type is B*, scoped in the global namespace. The friend function is scoped in the namespace containing the class that declares it - also the global namespace. So ADL will look in the global namespace for functions called f, find the friend function, and use that.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644