Я думаю, что ответ таков: самостоятельно реализовать такое поведение довольно тривиально, и, следовательно, Стандарт не чувствовал необходимости накладывать какие-либо правила на сам компилятор. Язык C ++ огромен, и не все можно представить перед его использованием. Взять, к примеру, шаблон C ++. Сначала он не был разработан для использования так, как сегодня (т. Е. Это возможность метапрограммирования). Поэтому я думаю, что стандарт просто дает свободу и не устанавливает никаких конкретных правил для std::move(other.p)
, следуя одному из принципов дизайна: «Вы не платите за то, что не используете» .
Хотя std::unique_ptr
является подвижным, но не копируемым. Так что если вы хотите указатель-семантику, которая может быть перемещаемой и копируемой одновременно, то вот одна из тривиальных реализаций:
template<typename T>
struct movable_ptr
{
T *pointer;
movable_ptr(T *ptr=0) : pointer(ptr) {}
movable_ptr<T>& operator=(T *ptr) { pointer = ptr; return *this; }
movable_ptr(movable_ptr<T> && other)
{
pointer = other.pointer;
other.pointer = 0;
}
movable_ptr<T>& operator=(movable_ptr<T> && other)
{
pointer = other.pointer;
other.pointer = 0;
return *this;
}
T* operator->() const { return pointer; }
T& operator*() const { return *pointer; }
movable_ptr(movable_ptr<T> const & other) = default;
movable_ptr<T> & operator=(movable_ptr<T> const & other) = default;
};
Теперь вы можете писать классы без написания собственной семантики перемещения:
struct T
{
movable_ptr<A> aptr;
movable_ptr<B> bptr;
//...
//and now you could simply say
T(T&&) = default;
T& operator=(T&&) = default;
};
Обратите внимание, что вам все еще нужно писать семантику копирования и деструктор, поскольку movable_ptr
это , а не умный указатель.