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

c++, incomplete-type, libc++, unique-ptr

Solution

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_;

Problem

I'm using the pimpl-idiom with `std::unique_ptr`: ``` class window { window(const rectangle& rect); private: class window_impl; // defined elsewhere std::unique_ptr<window_impl> impl_; // won't compile }; ``` However, I get a compile error regarding the use of an incomplete type, on line 304 in `<memory>`: Invalid application of '`sizeof`' to an incomplete type '`uixx::window::window_impl`' For as far as I know, `std::unique_ptr` should be able to be used with an incomplete type. Is this a bug in libc++ or am I doing something wrong here?

Original source

Related problems