Home > database >  Allowing access to protected member function for class outside of namespace
Allowing access to protected member function for class outside of namespace

Time:01-01

Consider the following code:

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

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

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

As currently constructed, this code will not compile - the friendship declared in class B applies to a (currently non-existent) A::C, and not the C in the global namespace. How can I work around this effectively, assuming I cannot add C to non-global namespace? I have tried using friend class ::C;, but the compiler does not like that. I have also tried forward declaring class C; before the namespace A scope, but that does not appear to work either.

CodePudding user response:

Adding a forward declaration for class C worked for me, what compiler are you using?

class C;

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

// ...

Live demo


Edit: as Vlad points out, both friend C and friend ::C also work, provided you have that forward declaration in place. But friend class C doesn't, I'll pass that one over to the language lawyers.

CodePudding user response:

The class C firstly is declared in the class B within namespace A. That is within the namespace A there is introduced the class C due to the elaborated type specifier and there is no previous declaration of the class.

The class C declared in the global namespace is a different class.

You need at first to declare the class C in the global namespace as

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(); }
};

In this case there is no need to use the elaborated type specifier

friend class C;

You could just write

friend C;

Otherwise without the forward declaration of the class C in the global namespace you need to declare the class C in the namespace A like

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

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

And in main you need to write

A::C c;
  • Related