Reputation: 123
I am trying to befriend a class in order for it to be able to reach a private constructor of it.
In some_file.h
class B;
namespace some_name {
class A {
public:
A() {}
private:
A (int x) {}
friend class ::B;
};
}
In other_file.h
#include "some_file"
namespace {
class B {
protected:
A* get_a(int x) { return new A(x); }
};
}
When compiling this code, I get - error: 'some_name::A::A(int)' is private.
I now, it is private, this is why I befriended B. What am I doing wrong here? Can't you befriend your constructor? Is there a namespace issue?
Thanks
Upvotes: 1
Views: 494
Reputation: 55736
Doing this:
namespace {
class B {
protected:
A* get_a(int x) { return new A(x) };
}
}
You're not putting B
in the root (global) namespace but in an anonymous one.
So B
can't be reached by ::B
.
If you want B
to be in the root (global) namespace, just don't enclose it with namespace
at all. This should do the trick.
Upvotes: 9
Reputation: 146930
You only forward declared and friended a class B in the global namespace. Not a class B in a namespace whatever. You need to fully qualify the name of B.
Edit: Thanks ereOn.
I made a slight mistake. It's true that the reason that you've got a problem is because you've mis-declared and mis-referred-to B, but my original statement wasn't quite true. You need to take B out of the anonymous namespace - it's pointless being in a header anyway.
Upvotes: 1
Reputation: 25497
Can't you befriend your constructor?
You can as shown below
struct B{
B();
void f();
};
struct A{
friend B::B();
private:
A(){}
};
B::B(){A a;} // fine
void B::f(){A a;} // error
int main(){
}
Upvotes: 0
Reputation: 58677
The problem is that you refer to B
as ::B
instead of B
. Meaning, you're telling the compiler that B
is a global name, but in fact it isn't: it's inside an anonymous namespace. You don't have to remove the anonymous namespace, it's just that it may not do what you expect it to do. Because the anonymous namespace is in a header it means what's inside that namespace is linked statically to any implementation file that includes the header. That's not very useful, because you hide nothing. You might as well remove that anonymous namespace.
Upvotes: 0