c++ - 不完整类型的 std::unique_ptr 无法编译

标签 c++ unique-ptr incomplete-type libc++

我将 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> 的第 304 行收到关于使用不完整类型的编译错误:

Invalid application of 'sizeof' to an incomplete type '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_;

关于c++ - 不完整类型的 std::unique_ptr 无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29970112/

相关文章:

c++ - 从工厂返回时向上转换 unique_ptr 的正确方法

c++ - 如何从 std::shared_ptr 转换为 std::unique_ptr?

c - C 中的参数类型不完整

c++ - 是否可以在没有编译失败的情况下推断类型是否不完整?

c++ - 是否可以用sizeof对void指针进行算术运算?

c++ - 使用流C++阅读换行符

c++ - 使用 operator[] 访问 unique_ptr 的私有(private) std::map

C++ dynamic_cast 转发声明的类模板编译,但它安全吗?

c++ - 比较字符串的 GetLine 工作一次然后比较不起作用

c++ - 矩阵模板类中的重载运算符* =和Operator +