Я не собираюсь повторять обоснование в @ замечательном ответе Натана Оливера , я просто собираюсь упомянуть как этого, механика, и это то, что я думаю вы тоже после. Вы правы в том, что если конструктор unique_ptr
выглядел просто как ...
explicit unique_ptr( T* ) noexcept;
... можно вывести T
. Сгенерированное компилятором руководство по выводам будет работать просто отлично. И это было бы проблемой, как показывает Натан. Но конструктор указан так ...
explicit unique_ptr( pointer p ) noexcept;
... где псевдоним pointer
указан следующим образом:
pointer
: std::remove_reference<Deleter>::type::pointer
если что
тип существует, в противном случае T*
. Должен удовлетворять NullablePointer .
Эта спецификация по сути означает, что pointer
должен быть псевдонимом __some_meta_function<T>::type
. Все, что слева от ::type
, представляет собой не выводимый контекст, который предотвращает вычитание T
из pointer
. Таким образом, такие руководства по выводам могут быть ошибочными, даже если pointer
должно быть всегда T*
. Просто сделав его не выводимым контекстом, вы предотвратите жизнеспособность любого руководства по выводам, созданного этим конструктором.