Please ignore the dubious inheritance pattern from a design point of view. Thanks :)
Consider the following case:
#include <memory>
struct Foo;
struct Bar : std::unique_ptr<Foo> {
~Bar();
};
int main() {
Bar b;
}
In both GCC and Clang, compiling this as an independent TU raises an error:
In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = Foo]':
required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = Foo; _Dp = std::default_delete<Foo>]'
error: invalid application of 'sizeof' to incomplete type 'Foo'
static_assert(sizeof(_Tp)>0,
^
This is GCC's, Clang's one is similar, and both point at the definition of struct Bar. Additionally, adding the missing definitions after main() fixes the error:
// Same as above
struct Foo { };
Bar::~Bar() = default;
It doesn't sound right to me that std::unique_ptr's destructor needs to be instantiated right when defining Bar, since it is only called by Bar's destructor which is defined out-of-line.
I find it even weirder that adding the definitions after everything else , where they shouldn't be reachable, apparently fixes the problem.
Should the first snippet be correct, and if not, why? What's happening in the second one that fixes it?