Ответ 1
В отношении (1) учтите, что он гарантирует, что и конструктор no-arg unique_ptr()
, и конструктор с нулевым указателем unique_ptr(nullptr_t)
имеют одинаковые гарантии времени компиляции, т.е. оба значения constexpr
. Мы можем видеть разницу в §20.8.1.2:
constexpr unique_ptr() noexcept;
explicit unique_ptr(pointer p) noexcept;
...
constexpr unique_ptr(nullptr_t) noexcept
: unique_ptr() { }
Почему два не были объединены в один конструктор со значением по умолчанию, вероятно, являются историческими обстоятельствами.
Что касается (2), почему мы должны заботиться о constexpr
, несмотря на отсутствие нетривиального деструктора, рассмотрим ответ, приведенный здесь:
Конструкторы
constexpr
могут использоваться для постоянной инициализации, которая, как форма статической инициализации, гарантирована, прежде чем произойдет любая динамическая инициализация.Например, с учетом глобального
std::mutex
:std::mutex mutex;
В соответствующей реализации (read: not MSVC) конструкторы других объектов могут безопасно блокировать и разблокировать конструктор
mutex
, becuasestd::mutex
constexpr
.