I have the following code:
struct M {
friend void f() {}
M() {
f(); // error: \'f\' was not declared in this scope
}
};
int main() {
This quote from the C++ Standard
A friend function defined in a class is in the (lexical) scope of the class in which it is defined.
means the following
9 Name lookup for a name used in the definition of a friend function (11.3) defined inline in the class granting friendship shall proceed as described for lookup in member function definitions.
That is any name used in the function is searched starting from the class scope.
However the function itself is not visible in the namespace until it will be declared outside the class.
So in your case it is enough to declare the function before the class definition
void f() {}
struct M {
friend void f();
M() {
f();
}
};
int main() {
M m;
}
Or
void f();
struct M {
friend void f() {}
M() {
f();
}
};
int main() {
M m;
}
The friend declaration states that a function called f
in the surrounding namespace is a friend of the class; but it does not introduce the name f
into the namespace. It's not available (except by argument-dependent lookup) until it's been declared in the namespace.
The relevant rule is C++11 7.3.1.2/3:
If a
friend
declaration in a non-local class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by unqualified lookup or by qualified lookup until a matching declaration is provided in that namespace scope.
The critical question is under what circumstances is the compiler able/allowed to find your function declaration.
For a general friend
function, you have to declare it outside of the class such that the compiler is able to find it.
However there is a very useful exception: If the the friend
function has an argument of class type, it is able to find the function without additional declaration due to argument-dependent name lookup.
This case is actually very important because normally you would want a friend
function to access an object of class type.
Consider the following example:
#include <iostream>
struct M
{
friend void printI(int a) {
std::cout << a;
}
friend void print(const M& m) { // friend takes object of class type!
std::cout << "M";
}
void foo() {
printI(2); // ERROR - requires declaration!
print(*this); // OK!
}
};
int main()
{
M m;
m.foo();
printI(2); // ERROR - requires declaration!
print(m); // OK
}
struct M {
friend void f() {}
M() {
f(); // error: 'f' was not declared in this scope
}
};
int main() {
M m;
}
The above code works perfectly.(tried on DevC++)
Also try not to define the function inside the class as it might not have a scope outside it i.e. in main()
.
In trying to call f()
from main()
you'll receive an error saying function doesn't exist.
Therefore, define function outside classes using ::
operator (if necessary) so that there is no problem accessing the function from anywhere.
Access friend function defined in class