A friend declaration for a non-member function inside a class grants that functon access to the class's private and protected members. However, such a declaration does not serve as a full function declaration in the surrounding scope. If the function is used before its actual definition or a separate declaration appears, the compiler will generate an error.
#include <iostream>
#include <string>
using namespace std;
class Person {
friend void fun();
public:
Person(string name, int age) : name_(name), age_(age) {
fun(); // Error: 'fun' not declared in this scope
}
private:
string name_;
int age_;
};
void fun() {
cout << "Friend of Person" << endl;
}
Too resolve this, either define fun() before the class or provide a separate declaration before its use:
class Person {
friend void fun();
void fun(); // Member function overload
public:
Person(string name, int age) : name_(name), age_(age) {
fun(); // Calls member function, not the friend
}
private:
string name_;
int age_;
};
void fun() {
cout << "Friend of Person" << endl;
}
If a non-member function is used outside the class before its definition—even if it was declared as a friend—a separate forward declaration is required:
class Person {
friend void fun();
void fun();
public:
Person(string name, int age) : name_(name), age_(age) {}
private:
string name_;
int age_;
};
void func() {
fun(); // Requires prior declaration of ::fun
}
void fun() {
cout << "Friend of Person" << endl;
}
This code fails unless void fun(); is declared before func().
Even when a friend function is defined inline within the class, the same rule applies—it is not automatically visible in the enclosing namespace unless a matching declaration exists:
class Person {
friend void fun() {
cout << "Friend of Person" << endl;
}
void fun();
public:
Person(string name, int age) : name_(name), age_(age) {
fun(); // Calls member function, NOT the friend
}
private:
string name_;
int age_;
};
However, once properly declared, the inline-defined friend can be called from outside:
class Person {
friend void fun() {
cout << "Friend of Person" << endl;
}
void fun();
public:
Person(string name, int age) : name_(name), age_(age) {}
private:
string name_;
int age_;
};
void fun(); // Required for external visibility
void func() {
fun(); // OK
}
int main() {
func();
return 0;
}