jeudi 10 juin 2021

How to access private Constructor from within inner class?

I am trying to apply the builder pattern to an object, but the private constructor is not visible from the inner class.

#include <iostream>
#include <memory>

class Outer{
private:
    Outer(void){ std::cout << "Constructed!" << std::endl; }
public:
    class Builder{
    public:
        std::unique_ptr<Outer> build(void){
            return std::make_unique<Outer>();
        }
    };
};

int main(int argc, char** agrs){
    std::unique_ptr<Outer> instance = Outer::Builder().build();
    return 0;
}

fails with the following error:


In file included from /usr/include/c++/8/memory:80,
                 from scrap.cpp:2:
/usr/include/c++/8/bits/unique_ptr.h: In instantiation of ‘typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = Outer; _Args = {}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<Outer>]’:
scrap.cpp:11:35:   required from here
/usr/include/c++/8/bits/unique_ptr.h:831:30: error: ‘Outer::Outer()’ is private within this context
     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
scrap.cpp:6:2: note: declared private here
  Outer(void){ std::cout << "Constructed!" << std::endl; }
  ^~~~~

I tried friend class Outer::Builder in the definition, but Outer is incomplete at the friend clause, so I couldn't make it work with that. I would very much like to restrict instantiation of the object to the Builder class, is there any way to do that in C++? Or is making the Outer constructor public the only option?

Aucun commentaire:

Enregistrer un commentaire