Reputation: 27395
There is a quote from 3.4.1/7:
When looking for a prior declaration of a class or function introduced by a friend declaration, scopes outside of the innermost enclosing namespace scope are not considered;
Can you get an example to demonstrate this rule?
Upvotes: 1
Views: 65
Reputation: 23011
This rule regulates where the compiler is looking for functions or classes marked as friend
. It regulates, that the compiler will only check functions or classes in the same namespace as the class which allows friend
access. It will not check functions or classes in other or outer namespaces.
This code will produce an error:
#include <iostream>
namespace a {
class Q { int x; friend void foo(Q q); };
}
// function foo is in outer namespace (not in a)
void foo(a::Q q) { std::cout << q.x << std::endl; }
// ^^^ ERROR q.x is private
int main() {
a::Q q;
foo(q);
}
The reason is that the function foo
is not in the namespace a
, but in an outer namespace (in this case the global namespace). Thus foo
does not match the friend declaration in Q
.
This code will work:
#include <iostream>
namespace a {
class Q { int x; friend void foo(Q q); };
}
// function foo is in same namespace as Q
namespace a {
void foo(Q q) { std::cout << q.x << std::endl; }
// ^^^ OK access allowed by friend
}
int main() {
a::Q q;
a::foo(q);
}
This works because the function foo
is now in the same namespace as Q
. Thus foo
matches the friend declaration in Q
.
Upvotes: 1
Reputation: 29966
Sure. This code works (both classes are in the same namespace):
namespace Foo {
class Bar
{
friend class FooBar;
public:
Bar() : i(0){}
private:
int i;
};
class FooBar
{
FooBar( Bar & other )
{
other.i = 1;
}
};
}//namespace Foo
And this code fails (the friend class is outside of the Foo
's enclosing namespace, thus the lookup fails and you see the the int Foo::i is private within this context
error):
namespace Foo {
class Bar
{
friend class FooBar;
public:
Bar() : i(0){}
private:
int i;
};
}//namespace Foo
class FooBar
{
FooBar( Foo::Bar & other )
{
other.i = 1;//Oops :'(
}
};
Upvotes: 1