Ответ 1
Я думаю, все это совершенно безопасно. Когда вы вызываете функцию f()
на foo
, оператор присваивания перемещения class Foo
будет вызывать std::unique_ptr<Foo>::operator=(std::unique_ptr<Foo>&&)
. Теперь, стандарт С++ 14, §20.8.1.2.3, запятая 2, говорит:
Эффекты: переносит право собственности с
u
на*this
, как если бы он вызывалreset(u.release())
, а затемget_deleter() = std::forward<D>(u.get_deleter())
.
В § 20.8.1.2.5, запятая 4, находим поведение reset()
:
Эффекты: назначает
p
сохраненному указателю, а затем, если старое значение сохраненного указателяold_p
не равноnullptr
, вызываетget_deleter()(old_p)
. [Примечание: порядок этих операций значителен, потому что вызовget_deleter()
может уничтожить*this
. -end note]
Итак, мы можем утверждать, что сохраненный указатель будет заменен, а , а затем старый сохраненный указатель будет удален в этом порядке. Таким образом, все хорошо и четко определено.
Кроме того, когда вы войдете в функцию reset()
, объект *foo.next
уже будет release()
d, поэтому указанный объект не будет уничтожен вместе с ним.