1. ホーム
  2. c++

[解決済み】std::unique_ptrが不完全な型だとコンパイルされない

2022-04-04 20:24:28

質問

pimpl-idiomを使用しています。 std::unique_ptr :

class window {
  window(const rectangle& rect);

private:
  class window_impl; // defined elsewhere
  std::unique_ptr<window_impl> impl_; // won't compile
};

しかし、不完全な型の使用に関して、コンパイルエラーが発生します。 <memory> :

の適用が無効です。 sizeof ' を不完全な型 ' uixx::window::window_impl '

私が知っている限りでは std::unique_ptr は不完全な型でも使用できるはずです。これはlibc++のバグでしょうか、それとも私がここで何か間違ったことをしているのでしょうか?

解決方法を教えてください。

以下はその例です。 std::unique_ptr を不完全な型とする。問題は破壊にあります。

でpimplを使用した場合 unique_ptr デストラクタを宣言する必要があります。

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

というのも、そうしないとコンパイラはデフォルトのものを生成してしまうからで、完全な宣言が必要なのは foo::impl を使用します。

もし、テンプレートコンストラクタがあるのであれば、たとえ impl_ メンバになります。

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

ネームスペース・スコープでは unique_ptr もうまくいきません。

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

というのは、コンパイラはこの静的デュレーションオブジェクトをどのように破棄するかをここで知っていなければならないからです。回避策としては

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