У вас просто есть опечатка:
template <typename uniq, typename ptr>
void set(uniq &u, const ptr &p){
u = std::unique_ptr<decltype(*std::declval<ptr>)>(p);
// ^^^
}
std::declval
- это функция, поэтому код, который вы пишете, пытается разыменовать этот тип функции.Что является действительным, что нужно сделать!Вот как вы получаете A*&& (&)() noexcept
То, что вы хотите:
template <typename uniq, typename ptr>
void set(uniq &u, const ptr &p){
u = std::unique_ptr<decltype(*std::declval<ptr>())>(p);
}
Что вы можете написать намного проще, просто используя имя p
:
template <typename uniq, typename ptr>
void set(uniq &u, const ptr &p){
u = std::unique_ptr<decltype(*p)>(p);
}
Но это, вероятно, не совсем правильно, поскольку decltype(*p)
обычно имеет ссылочный тип, и вы должны удалить его:
template <typename uniq, typename ptr>
void set(uniq &u, const ptr &p){
u = std::unique_ptr<std::remove_reference_t<decltype(*p)>>(p);
}
Теперь этот код на самом деле * только 1020 *работает с необработанным указателем (вам нужно move
a unique_ptr
и вы не можете преобразовать shared_ptr
в unique_ptr
), чтобы вы могли более четко выразить это в сигнатуре функции, которая также делаеткузов гораздо проще написать:
template <typename uniq, typename T>
void set(uniq &u, T* p){
u = std::unique_ptr<T>(p);
}
Что в конечном итоге вызывает вопрос, почему вы хотели бы написать:
set(dd, new A);
вместо:
dd = std::make_unique<A>();
в любом случае?2-й намного выше.