Объявление класса может быть одновременно определением класса.
Вы не можете поместить определение функции друга в класс, который не определяется.
Учтите, что если такая функция друга не объявлена вне класса, предоставляющего дружбу, то она невидим Он может быть найден только с помощью поиска имени в зависимости от аргумента.
Вот демонстрационная программа.
#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;
}
Вывод программы:
a.x = 10
x = 20
В этом вызове
f( A( 10 ) );
имя функции друга найдено из-за зависимого от аргумента поиска.
В этом вызове
( f )( A( 20 ) );
, заключив имя функции в скобки, отключает поиск, зависящий от аргумента, и вызывается функция, не являющаяся другом.
Или вы можете использовать квалифицированное имя функции, например
::f( A( 20 ) );
В этом случае ADL также не будет работать, и функция друга будет вызвана.
Также имейте в виду, что функция друга, определенная в классе, находится в лексической области видимости класса. Это означает, что он может использовать имена членов класса. Функция Friend, определенная вне класса, не входит в лексическую область класса.