假设我有一个类 F
应该是类 G
(在全局命名空间中)和 C
(在命名空间 A
)。
- 要成为
A::C
的 friend ,F
必须前向声明。 - 要成为
G
的 friend ,F
的前向声明是不必要的。 - 同样,类
A::BF
可以成为A::C
的 friend ,无需前向声明
以下代码说明了这一点,并可以使用 GCC 4.5、VC++ 10 以及至少一个其他编译器进行编译。
class G {
friend class F;
int g;
};
// without this forward declaration, F can't be friend to A::C
class F;
namespace A {
class C {
friend class ::F;
friend class BF;
int c;
};
class BF {
public:
BF() { c.c = 2; }
private:
C c;
};
} // namespace A
class F {
public:
F() { g.g = 3; c.c = 2; }
private:
G g;
A::C c;
};
int main()
{
F f;
}
在我看来,这似乎不一致。这是有原因的还是只是标准的设计决定?
最佳答案
C++
标准ISO/IEC 14882:2003(E)
7.3.1.2 命名空间成员定义
第 3 段
Every name first declared in a namespace is a member of that namespace. If a friend declaration in a non-local class first declares a class or function (this implies that the name of the class or function is unqualified) the friend class or function is a member of the innermost enclosing namespace.
// Assume f and g have not yet been defined. void h(int); template <class T> void f2(T); namespace A { class X { friend void f(X); // A::f(X) is a friend class Y { friend void g(); // A::g is a friend friend void h(int); // A::h is a friend // ::h not considered friend void f2<>(int); // ::f2<>(int) is a friend }; }; // A::f, A::g and A::h are not visible here X x; void g() { f(x); } // definition of A::g void f(X) { /* ... */} // definition of A::f void h(int) { /* ... */ } // definition of A::h // A::f, A::g and A::h are visible here and known to be friends }
你的 friend class BF;
是在命名空间 A 而不是全局命名空间中的 A::BF
声明。您需要全局先验声明来避免这个新声明。
关于c++ - 为什么 C++ 友元类只需要在其他命名空间中进行前向声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4492062/