boost::bind + boost::shared_ptr
-
Ich versuche der Funktion zum Freigeben einer Ressource einen Parameter zu binden. Ist das überhaupt möglich?
#include <iostream> #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> void Release(int*, const std::string& txt) { std::cout << txt << std::endl; } int main() { boost::shared_ptr<int> p((int*)0, boost::bind(Release, _2)("Hallo Welt")); // Funktioniert so leider nicht }
-
Was willst du machen? Welchen Sinn soll das haben? Verwechselst du da nicht etwas mit boost::function???
-
Ich will eine Funktion mit mehreren Parametern an boost::shared_ptr übergeben.
Das ganze hat sich erledigt, ich hab irgendwie boost::bind nicht ganz richtig verstanden, so klappt's:
#include <iostream> #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> void Release(int*, const std::string& txt) { std::cout << txt << std::endl; } int main() { boost::shared_ptr<int> p((int*)0, boost::bind(Release, _1, "Hallo Welt")); }
-
Genau, so klappts. Allerdings kommt man meist auch schön hin indem man sich einfach einen kleinen RAII Wrapper schreibt für die Resourcen die man verwalten möchte.
Wenn ich z.B. Win32 handles verwalten möchte nehme ich nicht einfach shared_ptr mit CloseHandle als deleter, sondern einen kleinen Wrapper ala so:struct Win32Handle { explicit Win32Handle(HANDLE h = 0) : m_h(h) {} ~Win32Handle() { if (m_h != 0 && m_h != INVALID_HANDLE_VALUE) { BOOL rc = ::CloseHandle(m_h); assert(rc); } } HANDLE m_h; // um es RAII nennen zu dürfen müsste m_h wohl const sein, // ist aber oft praktisch wenn es nicht const ist, // in dem Fall muss man halt u.U. selbst CloseHandle aufrufen // wenn man m_h modifiziert (das alte handle freigeben z.B.) };Das kann man dann schön mit shared_ptr verwenden, oder auch einfach als lokale Variable verwenden (ohne den Overhead von shared_ptr, was immerhin mindestens 2x new + 2x delete ist - also nicht ganz ohne).
-
Das wär wahrscheinlich besser, allerdings wird mein Handle erst spät initialisiert, deswegen mach ich es so:
static void ReleaseDC(HWND hwnd, HDC hdc) { if(!::ReleaseDC(hwnd, hdc)) std::cerr << "Release Device Context Failed." << std::endl; } // ... boost::shared_ptr<boost::remove_pointer<HDC>::type> pDeviceContext_; // ... pDeviceContext_.reset(GetDC(hwnd), boost::bind(ReleaseDC, hwnd, _1));Gibt's eigentlich ne schnellere Version als shared_ptr, die auch eine eigene Release-Funktion unterstützt? (Tut scoped_ptr ja glaub ich net)
-
Ich sehe nicht warum das mit einer kleinen Wrapper Klasse nicht gehen sollte, aber egal.
Und nein, ich kenne nix was einen deleter unterstützt und schneller als shared_ptr ist, aber wie gesagt, man kann sich ja in ein paar Zeilen selbst was schreiben was die Resource kapselt - dann funktioniert es auch mit scoped_ptr.
BTW: bei Handles (seis nun GDI oder KERNEL32) fallen die 2 new + delete die bei shared_ptr anfallen nicht so ins Gewicht, die Funktionen sind sowieso nicht gerade schnell. Genauso Dinge wie GetDC/ReleaseDC. Mach dir also nicht allzuviel Sorgen deswegen - wenn shared_ptr deiner Meinung nach Sinn macht, verwende es einfach.