C++ 寻找之前的声明,由朋友声明介绍
有一段引用自3.4.1/7: 在查找所引入的类或函数的先前声明时 通过友元声明,作用域位于最内层封闭 不考虑命名空间范围C++ 寻找之前的声明,由朋友声明介绍,c++,namespaces,friend,C++,Namespaces,Friend,有一段引用自3.4.1/7: 在查找所引入的类或函数的先前声明时 通过友元声明,作用域位于最内层封闭 不考虑命名空间范围 你能举出一个例子来演示这条规则吗?这条规则规定编译器在哪里查找标记为友元的函数或类。它规定,编译器只检查与允许friend访问的类位于同一命名空间中的函数或类。它不会检查其他名称空间或外部名称空间中的函数或类 此代码将产生一个错误: #include <iostream> namespace a { class Q { int x; friend void
你能举出一个例子来演示这条规则吗?这条规则规定编译器在哪里查找标记为
友元的函数或类。它规定,编译器只检查与允许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
现在与Q
位于同一名称空间中。因此,foo
与Q
中的友元声明相匹配。此代码有效(两个类位于同一命名空间中):
并且此代码失败(friend类在Foo
的封闭命名空间之外,因此查找失败,您会看到int Foo::i在此上下文中是私有的错误):
cppreference的部分对这一点和许多其他有趣的查找条件有相当可靠的描述。值得一读。
#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);
}
namespace Foo {
class Bar
{
friend class FooBar;
public:
Bar() : i(0){}
private:
int i;
};
class FooBar
{
FooBar( Bar & other )
{
other.i = 1;
}
};
}//namespace Foo
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 :'(
}
};