Consider this code:
namespace foo {}
class A
{
class B
{
};
friend int foo::bar( B& );
};
namespace foo
{
int bar( A::B& )
{
}
}
G++ 4.4.3 tells me:
friendfun-innerclass.cpp:21: error: 'int foo::bar(A::B&)' should have been declared inside 'foo'
But I can't declare:
namespace foo
{
int bar( A::B& );
}
before the class A definition because A::B hasn't been declared. And I can't declare "class A::B" obviously, to declare class B I have to give the definition of class A, and as far as I know the "friend" declarations have to be inside the definition of class A.
What's strange to me is that if I take function "bar()" out of namespace foo everything works fine. It seems counterintuitive to me that having a function inside a namespace or not inside a namespace changes whether the compiler will accept a friend function declaration in the class.
Does anybody know of a way to proprerly structure all the declarations and such to get this to work?
Friend functions can be defined (given a function body) inside class declarations. These functions are inline functions. 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 (at the end of the class declaration).
A friend function in C++ is defined as a function that can access private, protected and public members of a class. The friend function is declared using the friend keyword inside the body of the class.
The friend function can be a member of another class or a function that is outside the scope of the class. A friend function can be declared in the private or public part of a class without changing its meaning.
Friend Keyword in C++ But, to declare any class as a friend class, you do it with the friend keyword. You can use the friend keyword to any class to declare it as a friend class. This keyword enables any class to access private and protected members of other classes and functions.
Can't be done the way you want to, because you would have to forward declare a nested class (which you can't) in order to provide a prototype for foo::bar
.
As a first attempt to get around this problem, I would probably resort to making foo::bar
a function template. That way the compiler will resolve the types after A
and B
are known.
Test harness:
namespace foo
{
template<class B> int bar(B&);
};
class A
{
class B
{
template<class B> friend int foo::bar( B& );
int n_;
public:
B() : n_(42) {}
};
public:
B b_;
};
template<class B> int foo::bar(B& b)
{
return b.n_;
}
int main()
{
A a;
foo::bar(a.b_);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With