#c #unique-ptr #void-pointers #typetraits
#c #уникальный-ptr #void-указатели #typetraits
Вопрос:
Я использую std::unique_ptr
таким образом:
template <typename Pointer, auto deleter>
using my_unique_ptr = std::unique_ptr<std::remove_pointer<Pointer>, std::integral_constant<decltype(deleter), deleter>>;
Кажется, это работает, когда Pointer = void*
, но при попытке использовать reset для такого my_unique_ptr
, я получаю эту ошибку:
invalid conversion from 'SampleType' {aka 'void*'} to 'std::unique_ptr<std::remove_pointer<void*>, std::integral_constant<...> >::pointer' {aka 'std::remove_pointer<void*>*'}
Не std::remove_pointer<void*>*
должно автоматически означать void*
?
Ответ №1:
Ваш my_unique_ptr<void*>
не содержит void*
. Он содержит std::remove_pointer<void*>*
.
Не
std::remove_pointer<void*>*
должно автоматически означатьvoid*
?
std::remove_pointer
Тип не является волшебным. Это такой же тип, как и любой другой. Вот возможная реализация:
template<typename T>
struct remove_pointer {
using type = T;
};
template<typename T>
struct remove_pointer<T*> {
using type = T;
};
Как вы можете видеть, как вы его определили, std::unique_ptr
содержит указатель на эту структуру, как и упомянутая ошибка компилятора.
То, что вы, вероятно, хотели сделать, это использовать член ::type
структуры, он же результат remove_pointer
метафункции:
template <typename Pointer, auto deleter>
using my_unique_ptr = std::unique_ptr<typename std::remove_pointer<Pointer>::type, std::integral_constant<decltype(deleter), deleter>>;
А в C 14 есть псевдоним для упрощения:
template <typename Pointer, auto deleter>
using my_unique_ptr = std::unique_ptr<std::remove_pointer_t<Pointer>, std::integral_constant<decltype(deleter), deleter>>;