std::unique_ptr with an incomplete type won’t compile

Here are some examples of std::unique_ptr with incomplete types. The problem lies in destruction.

If you use pimpl with unique_ptr, you need to declare a destructor:

class foo
{ 
    class impl;
    std::unique_ptr<impl> impl_;

public:
    foo(); // You may need a def. constructor to be defined elsewhere

    ~foo(); // Implement (with {}, or with = default;) where impl is complete
};

because otherwise the compiler generates a default one, and it needs a complete declaration of foo::impl for this.

If you have template constructors, then you’re screwed, even if you don’t construct the impl_ member:

template <typename T>
foo::foo(T bar) 
{
    // Here the compiler needs to know how to
    // destroy impl_ in case an exception is
    // thrown !
}

At namespace scope, using unique_ptr will not work either:

class impl;
std::unique_ptr<impl> impl_;

since the compiler must know here how to destroy this static duration object. A workaround is:

class impl;
struct ptr_impl : std::unique_ptr<impl>
{
    ~ptr_impl(); // Implement (empty body) elsewhere
} impl_;

Leave a Comment