14 ms·
The reason why that code fails is explained by gcc's unique_ptr implementation: /// Primary template of default_delete, used by unique_ptr template<typ
by cmma 11y ago
The reason why that code fails is explained by gcc's unique_ptr implementation:
/// Primary template of default_delete, used by unique_ptr
template<typename _Tp>
struct default_delete
{
...
void
operator()(_Tp* __ptr) const
{
static_assert(!is_void<_Tp>::value,
"can't delete pointer to incomplete type");
static_assert(sizeof(_Tp)>0,
"can't delete pointer to incomplete type");
delete __ptr;
}
};
Basically, invoking "operator delete" on a pointer to an incomplete type (aka opaque pointer) is usually undefined. Calling "operator new" on an incomplete type is not possible (because its size is 0). Since unique_ptr deals with allocation/deallocation, and doesn't just copy pointer values around, it's not fully comparable to a plain pointer.
nice_byte proposed a good solution: if you can, abstract the new/delete logic to another file, in which the complete type of "Gadget" is known.
- ridiculous_fish 11y agoThat's true, but it's not obvious why anything in that code calls new or delete, since the destructor is defined elsewhere. So why does the constructor invoke operator delete? The missing puzzle piece is apparently exception handling: if the implicit constructor throws (which of course it cannot) it must delete this object (which of course will be null). Sadly this silly requirement persists even when exception handling is disabled at the compiler level.