Why does the make_unique call compile? Doesn't make_unqiue require its template argument to be a complete type ?
struct F;
int main()
{
std::make_unique<F>();
}
struct F {};
The question orignated from my "problem" with my PIMPL implementation:
I do understand why the destructor has to be user declared and defined inside the cpp file for the Implementation class (PIMPL).
But moving the constructor of the class containing the pimpl- still compiles.
class Object
{};
class CachedObjectFactory
{
public:
CachedObjectFactory();
~CachedObjectFactory();
std::shared_ptr<Object> create(int id) const;
private:
struct CacheImpl;
std::unique_ptr<CacheImpl> pImpl;
};
Now the cpp file:
// constructor with make_unique on incomplete type ?
CachedObjectFactory::CachedObjectFactory()
: pImpl(std::make_unique<CacheImpl>())
{}
struct CachedObjectFactory::CacheImpl
{
std::map<int, std::shared_ptr<Object>> idToObjects;
};
//deferred destructor
CachedObjectFactory::~CachedObjectFactory() = default;
Could someone explain why this compiles? Why is there a difference between construction and destruction? If the instantiation of the destructor and the instantiation of the default_deleter is a problem why is the instantiation of make_unique not a problem ?
CacheImpl
in the .cpp file? I doubt that this compiles, for creation as well as desctrution, the type ofCacheImpl
must be known. – Leftystruct F; int main() { std::make_unique<F>(); } struct F{};
– Christopherunique_ptr
require a complete type. – Declinometerstruct Foo; int main(){ std::make_unique<Foo>(); } struct Foo { ~Foo() = delete; };
I've made it part of my answer, thanks for the shorthand! : ) – Vallonia