c++ - 为什么 C++ 友元类只需要在其他命名空间中进行前向声明?

标签 c++ namespaces friend forward-declaration

假设我有一个类 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/

相关文章:

c++ - gstreamermm:如何提取 Gst::PlayBin 的最后一个视频帧

php - 是否可以在 MediaWiki 中拥有自定义类别 namespace ?

php - Mustache.php 从命名空间内启动 - include() : failed to open stream

c++ - "friend"一个类是否扩展到该类中声明的类?

c++ - 我可以在编译时强制该函数永远不会被调用吗?

C++ _tmain 不会开始运行

c++ - 如何每 x 秒调用一个函数

c# - 命名空间和类之间的名称冲突

c++ - friend 类不工作

c++ - 什么时候必须使用友元函数而不是成员函数?