Ich arbeite viel mit Windows-API. Jedes Mal, wenn ich eine Art von Betriebssystem-Ressource (wie ein Handle. Registrierungsschlüssel, Socket usw.) bekomme, wickle ich es manuell mit einer Art von unique_ptr<HandleType,SomeDeleter>
, um mit dem richtigen Schließen dieses Handle umzugehen.toUniquePtr Implementierung
Ich versuche eine Lightwight toUniquePtr
Funktion zu erstellen, die eine Handle und eine Closing-Funktion erhält und automatisch eine unique_ptr
aus den beiden erstellt.
für exmaple:
auto ptr = CreateFile(/**/);
auto unique = toUniquePtr(ptr,&CloseHandle);
Meine Implementierung bisher:
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);
}
Beispiel Verwendung + Übersetzungsfehler *:
void* handle = malloc(100);
auto ptr = toUniquePtr(handle, &free);
Der Fehler, den ich von Visual Studio bekommen 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 *'
Was ist komisch. irgendeine Hilfe?
* Nein, ich benutze nicht malloc
in meiner täglichen Arbeit in C++, es ist nur für das Beispiel, da es eine einfache Funktion ist, den Kompilierungsfehler zu replizieren.
wird den Aufruf der Copykonstruktor aus irgendeinem Grund. Der Kopierkonstruktor wird für "unique_ptr" gelöscht. –
Meinst du nicht 'inline auto toUniquePtr (T * t, F f) {', dh, 'T' wird derzeit als Zeigertyp –
@PiotrSkotnicki hergeleitet, es sollte dem Compiler sowieso egal sein, und einiges Ressourcen sind keine Zeigertypen (zB SOCKET) und haben den Kompilierungsfehler nicht gelöst. –