I'm having difficulty understanding why the following MWE does not compile:
#include <iostream>
namespace N
{
class Foo
{
friend void bar( Foo& f );
void print(){ std::cout << "..." << std::endl; } // private by default
};
}
void bar( N::Foo& f )
{
f.print();
}
int main()
{
}
g++ 4.8.2 error
Test.cpp: In function ‘void bar(N::Foo&)’:
Test.cpp:8:8: error: ‘void N::Foo::print()’ is private
void print(){ std::cout << "..." << std::endl; } // private by default
^
Test.cpp:14:10: error: within this context
I'm almost certainly missing something here but surely the friend function bar()
can access any private member of the class N::Foo
.
Note that:
bar()
into the namespace N
resolves this error.::bar()
does not call N::Foo::print()
Why doesn't the code compile as is?
Edit
On second thoughts the title of this question does not precisely describe the problem. I'll edit it in due course.
An unqualified friend declaration refers to a function in the namespace containing the class, introducing that function into the namespace if it hasn't already been declared.
I'd move the function into the namespace. It can be found by argument-dependent lookup, so you can call it with an unqualified bar(foo)
without the need for N::
.
If you do want it in the global namespace for some reason, then you'll need to declare it in the global namespace before you can declare it a friend. This is a bit messy:
// Need the class definition to declare the function
namespace N {class Foo;}
// Need the function definition to declare it a friend
void bar( N::Foo& );
// Need the class definition to define the function
namespace N
{
class Foo
{
friend void ::bar( Foo& f );
void print(){ std::cout << "..." << std::endl; } // private by default
};
}
// And finally the function
void bar( N::Foo& f )
{
f.print();
}