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