Can't access private constructor from a friend class

522 Views Asked by At

In the following code snippet, g++ compiler outputs the following error:

error: ‘B::B(const string&)’ is private within this context 857 |
{ return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }

Commenting out the line where smart pointers are used seem to work. However, I'm not sure why it works for the other cases, and still not work for the smart pointer case.

#include <memory>
#include <iostream>
#include "string"

class A;

class B
{
    friend class A;
    B(const std::string& dummyString) { std::cout << dummyString << std::endl; }
};

class A
{
public:
    A()
    {
        B b("dummy1");
        B* pB1 = new B("dummy2");
        std::unique_ptr<B> pB2 = std::make_unique<B>("dummy3");
    }
};

int main()
{
    A a;
}
2

There are 2 best solutions below

0
wohlstad On BEST ANSWER

The problem is that make_unique which is supposed to construct an instance of B is not a friend of B. Therefore it does not have access to B's private constructor.

You can use the following to achieve something similar:

std::unique_ptr<B> pB2 = std::unique_ptr<B>(new B("dummy3"));

In general it is advised to prefer make_unique to calling new yourself, and I do not encourage it in any way (see here: Differences between std::make_unique and std::unique_ptr with new).
But if you are bound to this specific class hirarchy it will solve your issue.

0
user12002570 On

The problem is that make_unique internally uses the private constructor B::B(const std::string& ). But since make_unique itself is not a friend of A, we get the mentioned error.

To solve this you can either get rid of make_unique and directly use unique_ptr with new as shown here or make the ctor public.