0

I have found that friend function can be defined inside class declaration. I am a little bit confused about what does it mean due to a class declaration does not provide it's body, in general it just class A;.

Friend functions can be defined (given a function body) inside class declarations. These functions are inline functions, and like member inline functions they behave as though they were defined immediately after all class members have been seen but before the class scope is closed (the end of the class declaration). Friend functions that are defined inside class declarations are in the scope of the enclosing class.

Source: https://learn.microsoft.com/en-us/cpp/cpp/friend-cpp?view=vs-2019

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
michalt38
  • 1,193
  • 8
  • 17
  • 2
    My guess is that it's just a mistake, and they mean "inside a class *definition*" – cigien Apr 23 '20 at 20:31
  • [cppreference](https://en.cppreference.com/w/cpp/language/class) seems to say that `class A;` is a forward declaration, and `class A { /* ... */ }` would also be a declaration (it would declare the members of the class). https://stackoverflow.com/a/1410632 seems to disagree. I thought that all definitions were also declarations. – Artyer Apr 23 '20 at 20:37

2 Answers2

0

It means that

class A
{
public:
    friend std::ostream& operator << (std::ostream& os, const A&a)
    {
        return os << a.m1 << a.m2;
    }
};

is equivalent to

class A
{
public:
    friend std::ostream& operator << (std::ostream& os, const A&a);
};

inline std::ostream& operator << (std::ostream& os, const A&a)
{
    return os << a.m1 << a.m2;
}
Jasper Kent
  • 3,546
  • 15
  • 21
0

A class declaration can be at the same time a class definition.

You can not place a friend function definition in a class that is not being defined.

Take into account that if such a friend function is not also declared outside the class granting the friendship then it is invisible. It can be found only by the argument dependent name lookup.

Here is a demonstrative program.

#include <iostream>

class A
{
private:
    int x;

public:
    A( int x ) : x ( x ) {}
    operator int() const { return x; }
    friend void f( const A &a )
    {
        std::cout << "a.x = " << a.x << '\n';
    }
};

void f( int x )
{
    std::cout << "x = " << x << '\n';
}

int main() 
{
    f( A( 10 ) );
    ( f )( A( 20 ) );

    return 0;
}

The program output is

a.x = 10
x = 20

In this call

f( A( 10 ) );

the name of the friend function is found due to the argument dependent lookup.

In this call

( f )( A( 20 ) );

enclosing the function name in parentheses switches off the argument dependent look up and the non-friend function is called.

Or you could use a qualified function name like

::f( A( 20 ) );

In this case the ADL also will not work and the non-friend function will be called.

Also bear in mind that friend function defined in a class is in the lexical scope of the class. It means that it can use names of members of the class. Friend function defined outside a class is not in the lexical scope of the class.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335