none
Aus der MSDN-Entwickler-Hotline: Wie kann ich einen Smartpointer für std::bind in eine Reference umwandeln? RRS feed

  • Allgemeine Diskussion

  • Hallo zusammen,
    heute wurde uns bei der MSDN-Entwickler-Hotline unter anderem folgende Frage gestellt:

    Wie kann ich einen Smartpointer für std::bind in eine Reference umwandeln?

    Unsere Antwort bzw. unser Lösungsvorschlag darauf war:

    std::bind [1] stellt eine einfacheund flexible Möglichkeit für die Benutzung von Funktionspointer dar.Dabei können auch Argmente gebunden werden, ohne dass ein Funktionsaufruf stattfindet.

    void test(std::string v)
    {
        std::cout << v << std::endl;   
    }
        
        
    std::function<void()> func = std::bind(&test, "Hello World!");
    
    // Argument für test bereits gebunden
    func();

    Gegeben sei nun eine Funktion, die eine Referenz entgegen nimmt und den hinterlegten Wert manipuliert.

    void assign(std::string& target, const std::string& source)
    {  
        target = source;
    }

    Soll nun der erste Parameter gebunden werden, liegt dieser aber nur als smart pointer vor,findet keine automatische Konversion statt.

    std::shared_ptr<std::string> pstr = ...
    
    // Kompilerfehler! shared_ptr<std::string> kann nicht in string-Referenz umgewandelt werden
    std::function<void(const std::string&)> func = std::bind(&assign, pstr, std::placeholders::_1);
    func("test");

    Um dieses Problem zu umgehen und gleichzeitig den smart pointer nicht zu verlieren, brauchen wir eine Klasse, die die Konvertierung übernimmt.

    template<typename T, typename Target>
    class ptr_wrapper
    {
    public:
    	ptr_wrapper(T _ptr)
    		: ptr(_ptr)
    	{
    	}
    
    	operator Target() const 
    	{
    		return *ptr;
    	}
    
    private:
    	T ptr;
    };
    
    
    /// Eine kleine Hilfsfunktion
    template<typename T>
    auto  as_ref(T ptr) -> ptr_wrapper<T, decltype(*ptr)>
    {
    	return ptr_wrapper<T, decltype(*ptr)>(ptr);
    }

    // Nun kann der as_ref ganz einfach genutzt werden:

    std::shared_ptr<std::string> pstr = ...
    
    // Kompilerfehler! shared_ptr<std::string> kann nicht in string-Referenz umgewandelt werden
    std::function<void(const std::string&)> func = std::bind(&assign, as_ref(pstr), std::placeholders::_1);
    func("test");

    [1] http://de.cppreference.com/w/cpp/utility/functional/function

    Wir hoffen, vielen Besuchern der MSDN Foren durch das Posten dieses Problems und einer möglichen Lösung weiterhelfen zu können.

    Viele Grüße,

    Entwickler-Hotline für MSDN Online Deutschland

    Disclaimer:
    Bitte haben Sie Verständnis dafür, dass wir hier auf Rückfragen gar nicht oder nur sehr zeitverzögert antworten können.
    Bitte nutzen Sie für Rückfragen oder neue Fragen den telefonischen Weg über die MSDN-Entwickler-Hotline: http://www.msdn-online.de/Hotline
    MSDN-Entwickler-Hotline: Schnelle & kompetente Hilfe für Entwickler: kostenfrei!

    Es gelten für die MSDN-Entwickler-Hotline und dieses Posting diese Nutzungsbedingungen , Hinweise zu Markenzeichen, Informationen zur Datensicherheit sowie die gesonderten Nutzungsbedingungen für die MSDN-Entwickler-Hotline .

    Montag, 29. September 2014 11:36