Пожалуйста, игнорируйте сомнительную модель наследования с точки зрения дизайна. Спасибо 🙂
Рассмотрим следующий случай:
#include <memory>
struct Foo;
struct Bar : std::unique_ptr<Foo> {
~Bar();
};
int main() {
Bar b;
}
И в GCC, и в Clang компиляция этого как независимого TU вызывает ошибку:
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,
^
Это GCC, Clang один, и оба указывают на определение struct Bar
, Кроме того, добавление отсутствующих определений после main()
исправляет ошибку:
// Same as above
struct Foo { };
Bar::~Bar() = default;
Мне кажется, это неправильно std::unique_ptr
деструктор должен быть создан прямо при определении Bar
так как он вызывается только Bar
деструктор, который определен вне линии.
Я считаю еще более странным, что добавление определений после все остальное, где они не должны быть доступны, по-видимому, решает проблему.
Должен ли первый фрагмент быть правильным, а если нет, то почему? Что происходит во втором, что исправляет это?
Задача ещё не решена.
Других решений пока нет …