允许访问命名空间外 class 的受保护成员函数

Allowing access to protected member function for class outside of namespace

考虑以下代码:

namespace A
{
  class B
  {
  protected:
    friend class C;
    static void foo();
  };
}

class C
{
public:
  C() { A::B::foo(); }
};

int main()
{
  C c;
  return 0;
}

按照目前的构造,此代码将无法编译 - class B 中声明的友谊适用于(当前不存在的)A::C,而不是全局中的 C命名空间。假设我不能将 C 添加到非全局命名空间,我该如何有效地解决这个问题?我试过使用 friend class ::C;,但编译器不喜欢那样。我也尝试在 namespace A 范围之前向前声明 class C;,但这似乎也不起作用。

为 class 添加前向声明 C 对我有用,您使用的是什么编译器?

class C;

namespace A
{
  class B
  {
  protected:
    friend class ::C;
    static void foo();
  };
}

// ...

Live demo


编辑: 正如 Vlad 指出的那样,friend Cfriend ::C 也都有效,前提是您有该前向声明。但是 friend class C 没有,我会把那个交给语言律师。

class C 首先在命名空间 A 中的 class B 中声明。在命名空间 A 中,由于详细的类型说明符而引入了 class C,并且class.

之前没有声明

在全局命名空间中声明的class C 是不同的class。

首先需要在全局命名空间中声明class C为

class C;
namespace A
{
    class B
    {
    protected:
        friend class C;
        static void foo() {
            std::cout << "Hello World!\n";
        }
    };
}

class C
{
public:
    C() { A::B::foo(); }
};

在这种情况下,无需使用详尽的类型说明符

friend class C;

你可以直接写

friend C;

否则,在全局命名空间中没有 class C 的前向声明,您需要在命名空间 A 中声明 class C,例如

namespace A
{
    class B
    {
    protected:
        friend class C;
        static void foo() {
            std::cout << "Hello World!\n";
        }
    };
}

namespace A
{
    class C
    {
    public:
        C() { B::foo(); }
    };
}

主要是你需要写

A::C c;