vsoftco
vsoftco

Reputation: 56547

unique_ptr pimpl and incomplete types

This is not a dupe of std::unique_ptr with an incomplete type won't compile.

Consider the code below:

#include <memory>

struct X
{
    X();
    ~X();    

    struct Impl; 
    std::unique_ptr<Impl> up_;
};

struct Impl {}; // fully visible here

X::X() : up_{nullptr}{}
X::~X() = default;

int main()
{
    X x;
}

Live on Coliru

gcc/clang both spit an error saying that Impl is incomplete. However, I provide a default destructor for X after Impl is fully visible, so IMO the code should compile. Why doesn't? Now comes the surprise: If I make Impl an inner class, i.e. define

struct X::Impl{};

instead, then the code compiles, even without providing a destructor. Why is this happening? Shouldn't we provide such a default destructor, at least according to the link mentioned in the first line?

Upvotes: 3

Views: 1034

Answers (1)

Miles Budnek
Miles Budnek

Reputation: 30494

You have two different structs named Impl.

struct X
{
    struct Impl; // Here you declare X::Impl
    std::unique_ptr<Impl> up_;  // Here you create a pointer to a X::Impl
};

struct Impl {};  // Here you declare and define ::Impl

...

int main()
{
    X x;  // Here X::Impl is still incomplete
}

Upvotes: 12

Related Questions