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_;
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…