In my previous post, "Why you shouldn't provide an empty destructor," we discussed the importance of not providing an empty destructor in most cases. However, in this post, we'll explore a rare exception to this rule that arises when using the PImpl idiom to hide implementation details, specifically in situations where the unique_ptr
encounters issues with incomplete types. Let's delve into this exception and learn when it's necessary to provide an empty destructor.
When an Empty Destructor is Required
by Andreas Fertig
From the article:
As you probably know from life, not only programming. There is no rule without an exception. Let's talk about the one case that requires an empty destructor (yes, I know it sounds silly). Suppose you have the following code:
In file included from <source>:2: In file included from /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/memory:76: /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/unique_ptr.h:93:16: error: invalid application of 'sizeof' to an incomplete type 'Orange' static_assert(sizeof(_Tp)>0, ^~~~~~~~~~~ /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/unique_ptr.h:396:4: note: in instantiation of member function 'std::default_delete<Orange>::operator()' requested here get_deleter()(std::move(__ptr)); ^ <source>:4:7: note: in instantiation of member function 'std::unique_ptr<Orange>::~unique_ptr' requested here class Apple ^ <source>:6:27: note: forward declaration of 'Orange' std::unique_ptr<class Orange> mOrange{}; ^ 1 error generated. Compiler returned: 1
Essentially, this message tells you that thestd::unique_ptr
cannot instantiate the required destructor for itself typed withOrange
. The simple reason is that, at this point,Orange
has no visible destructor. Which is the entire point of the PImpl idiom. What now?
Add a Comment
Comments are closed.