2012-04-01 8 views
2

mir den folgenden Code verwenden:Capture std :: Funktion von Wert

struct WorkData 
{ 
    std::string name; 
    std::function<void(std::string)> Callback; 

    WorkData(){}; 
    WorkData(const WorkData& other) 
    { 
     name = other.name; 
     Callback = std::ref(other.Callback); 
    } 
}; 

WorkData data; // this is the data to pass to queue_task() function bellow 
data.Callback = std::bind(&ResultProcessor::Handler, resProc, std::placeholders::_1); 

template <typename Functor> 
void queue_task(Functor& fn, WorkData& workData) 
{ 
    group.run([&fn, workData](){ 
      workData.Callback("resultComming"); // runtime ERROR- access violation 
    }); 
} 

queue_task Funktion Warteschlangen asynchron auf einem anderen Thread ausgeführt werden arbeiten (durch group.run (lambda) von oben Aufruf). Das Problem, das ich erfahre, ist, dass ich eine Zugriffsverletzung erhalte, wenn ich versuche, workData.Callback() aufzurufen.

Der Grund, warum ich eine Kopie von workData in group.run() mache, ist, weil ich workData nach Wert erfassen will, so dass wenn das group.run() Lambda ausgeführt wird, eine Kopie des Status hat, wenn queue_task() war namens. Ich würde erwarten, dass workData.Callback() auf der Instanz des Objekts weitergegeben Linie ausführen würde:

data.Callback = std::bind(&ResultProcessor::Handler, resProc, std::placeholders::_1); 

EDIT: resProc von oben lebt (nicht zerstört), wenn die Crash-Linie

Antwort

1

Die Verwendung genannt wird std::ref in Ihrem Kopierkonstruktor bedeutet, dass Sie einen Verweis auf die WorkData 's Callback Member behalten, keine Kopie. Sie wollen Callback = other.Callback eine Kopie erstellen, um eine Zugriffsverletzung zu vermeiden (wahrscheinlich von dem Zugriff auf den alten Rückruf nach dem Freigeben). Um einen Verweis auf resProc in der std::function zu behalten, müssen Sie std::ref(resProc) in den Anruf zu std::bind verwenden.

+0

Ich habe das EDIT in meiner Frage justiert. Ich benutze std :: ref, weil ich am Ende workData.Callback ("resultComming") auf einer anderen Instanz von ResultProcessor – Ghita

+0

aufrufen werde. In diesem Fall müssen Sie 'std :: ref' auf dem' ResultProcessor' verwenden, nicht die Funktion Objekt selbst. Das heißt, in Ihrem letzten Codeblock sollten Sie 'std :: ref (resProc)' haben und dann eine echte Kopie der 'std :: function' in Ihrem Kopierkonstruktor verwenden. –

+0

ResultProcessor-Instanz wird neben std :: function Callback als Teil von WorkData in queue_task() Schnittstelle – Ghita