С C ++ 11 мы получили конструкторы перемещения и семантику rvalues.
std :: move (X) - это просто приведение к r-значению, которое преобразует X в X &&, то есть в него.Чем Move ctor берет на себя работу и перемещает конструкторы, как правило, «крадет» ресурсы, удерживаемые аргументом.unique_ptr есть ход ctor.
Возвращаемые значения функции уже являются rvalue (если только функция не возвращает ссылку lvalue, как указано @HolyBlackCat в комментариях), которая запускает ctor перемещения без необходимости дополнительного приведения.И так как Move Ctor определен для unique_ptr, он скомпилируется.
Также причина сбоя v.push_back (p1); заключается в следующем: вы пытаетесь вызвать конструктор копирования с lvalue, и это не удается, потому что unique_ptr не имеет копии ctor.