Home >Backend Development >C++ >Why Does `std::unique_ptr` Fail with Incomplete Types in Pimpl Idiom?

Why Does `std::unique_ptr` Fail with Incomplete Types in Pimpl Idiom?

DDD
DDDOriginal
2024-12-13 05:01:11460browse

Why Does `std::unique_ptr` Fail with Incomplete Types in Pimpl Idiom?

std::unique_ptr and Incomplete Types: A Deeper Look

Consider the pimpl idiom employing 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, a compile error arises due to an incomplete type:

"Invalid application of 'sizeof' to an incomplete type 'uixx::window::window_impl'"

Traditionally, std::unique_ptr is compatible with incomplete types. So, where lies the issue?

The Crux of the Matter: Destruction

The key resides in destruction. If pimpl is used with unique_ptr, the destructor must be declared explicitly:

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

public:
    foo(); // Constructor may need external definition

    ~foo(); // Implement (braceless or with = default;) once impl is complete
};

If not, the compiler generates a default destructor requiring a complete declaration of foo::impl.

Template Problems and Static Duration Instances

With template constructors, complications arise even if the impl_ member is not constructed:

template <typename T>
foo::foo(T bar) {
    // Compiler requires knowledge of impl_ destruction at compile time!
}

Additionally, using unique_ptr with incomplete types at namespace scope fails:

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

The compiler needs to know how to destroy this static duration object. A workaround involves defining a custom type:

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

The above is the detailed content of Why Does `std::unique_ptr` Fail with Incomplete Types in Pimpl Idiom?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn