引用自3.4.1 / 7:
在寻找引入的类或函数的事先声明时 由朋友声明,范围在最里面的封闭 不考虑名称空间范围;
您能举例说明这条规则吗?
答案 0 :(得分:1)
此规则规定编译器查找标记为friend
的函数或类的位置。它规定,编译器只检查与允许friend
访问的类相同的命名空间中的函数或类。它不会检查其他名称空间或外部名称空间中的函数或类。
此代码将产生错误:
#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);
}
原因是函数foo
不在名称空间a
中,而是在外部名称空间中(在本例中是全局名称空间)。因此foo
与Q
中的朋友声明不匹配。
此代码可以使用:
#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);
}
这是有效的,因为函数foo
现在与Q
位于同一名称空间中。因此,foo
与Q
中的朋友声明匹配。
答案 1 :(得分:1)
不确定。此代码有效(两个类都在同一名称空间中):
namespace Foo {
class Bar
{
friend class FooBar;
public:
Bar() : i(0){}
private:
int i;
};
class FooBar
{
FooBar( Bar & other )
{
other.i = 1;
}
};
}//namespace Foo
此代码失败(友元类在Foo
的封闭命名空间之外,因此查找失败并且您看到int Foo::i is private within this context
错误:
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 :'(
}
};