Я много работаю с Windows API. каждый раз, когда я получаю какой-то ресурс ОС (например, дескриптор ключа реестра, сокет и т. д.), я обматываю его вручную с помощью своего рода unique_ptr<HandleType,SomeDeleter>
, чтобы иметь дело с правильным закрытием этого дескриптора.toUniquePtr реализация
Я пытаюсь создать функцию lightwight toUniquePtr
, которая получает ручку и функцию закрытия и автоматически создает unique_ptr
из двух.
для exmaple:
auto ptr = CreateFile(/**/);
auto unique = toUniquePtr(ptr,&CloseHandle);
Моя реализация до сих пор:
template <class T, class ClosingFunction>
struct CostumeDeleter {
ClosingFunction closingFunction;
CostumeDeleter(ClosingFunction closingFunction_) :
closingFunction(closingFunction_) {}
CostumeDeleter(const CostumeDeleter&) = default;
CostumeDeleter(CostumeDeleter&&) = default;
void operator() (T t) {
closingFunction(t);
}
};
template <class T, class F>
inline auto toUniquePtr(T t, F f) {
CostumeDeleter<T, F> deleter(f);
std::unique_ptr<T, decltype(deleter)> pointer(t, deleter);
return std::move(pointer);
}
Пример использования + ошибки компиляции *:
void* handle = malloc(100);
auto ptr = toUniquePtr(handle, &free);
Я получаю ошибку от визуального студии 2015 RTM 1 :
Error C2664 'std::unique_ptr<T,CostumeDeleter<T,F>>::unique_ptr(const std::unique_ptr<T,CostumeDeleter<T,F>> &)': cannot convert argument 1 from 'void *' to 'void *'
Что странно. любая помощь?
* Нет, я фактически не использую malloc
в своей повседневной работе на C++, это просто для примера, поскольку его простая функция реплицирует ошибку компиляции.
это звонит конструктор копирования для какой-либо причины. Конструктор копирования удаляется для 'unique_ptr'. –
Вы не имели в виду 'inline auto toUniquePtr (T * t, F f) {', т.е. 'T' в настоящее время выводится как тип указателя –
@PiotrSkotnicki, в любом случае это не имеет значения для компилятора, а некоторые ресурсы не являются типами указателей (например, SOCKET) и, во всяком случае, это не решило ошибку компиляции. –