Per [class.copy.ctor] / 8
Если определение класса X явно не объявляет конструктор перемещения, неявный будетнеявно объявляется дефолтным, если и только если [...]
- X не имеет объявленного пользователем деструктора.
С
virtual ~foo() = default;
- это деструктор, объявленный пользователем, у вас больше нет конструктора перемещения, поэтому он пытается использовать конструктор копирования, но не может этого сделать, потому что он удален, поскольку у вас есть не копируемый элемент.
Чтобы получитьпереместите конструктор назад, и чтобы сохранить конструкцию по умолчанию, вам нужно добавить
foo() = default;
foo(foo&&) = default;
foo &operator=(foo &&) = default; // add this if you want to move assign as well
к foo
Причина, по которой вы должны добавить foo() = default;
при добавленииfoo(foo&&) = default;
заключается в том, что foo(foo&&) = default;
является конструктором, который используется и если у вас есть какие-либо конструкторы, объявленные пользователем, тогда конструктор по умолчанию больше не предоставляется.
Это "взлом", но выможно было бы переместить виртуальный деструктор в другой класс, а затем наследовать от него.Это даст вам виртуальный деструктор в foo
без необходимости объявлять его и даст вам необходимые конструкторы по умолчанию.Это будет выглядеть как
struct make_virtual
{
virtual ~make_virtual() = default;
};
struct foo : make_virtual {
std::unique_ptr<int> mem;
};