2017-11-05 4 views
0

ich derzeit versuche zu implementieren ein Messenger-System für meine Spiel-Engine verwenden. Es nutzt Funktion Rückrufe der Form:Wie std :: bind für das Hinzufügen von Mitglied Rückruf zu einem Messenger-System

typedef std::function<void(const Message &)> Callback; 

ich alle Objekte auf eine Nachricht eines bestimmten Typs abonnieren können, wollen (wo der Typ ist nur ein String). Subskribieren bedeutet das Hinzufügen ihrer "onEvent" -Funktion zum Wörterbuch der Rückrufe.

mutable std::map<std::string, std::vector<Callback>> callbackDictionary; 

Die Update-Funktion dann diese Funktionen aufruft und die entsprechende Meldung (aus dem die „onEvent“ -Funktionen ihre Daten bekommen kann)

for each (auto message in messageList) 
{ 
    // find the list of respective callbacks 
    auto it = callbackDictionary.find(message->GetType()); 

    // If there are callbacks registered for this message type 
    if (it != callbackDictionary.end()) 
    { 
     // call every registred callback with the appropreate message 
     for each (auto callback in it->second) 
      callback(*message); 
    } 
} 

Nun, mein Problem ist, dass ich bin nicht ganz sicher, wie man diese "onEvent" -Funktionen bindet. Ich habe gerade vor kurzem wechselte zu C++ 11 und das Konzept der Funktionsobjekte und std::bind ist ganz neu für mich. Also hier ist das, was ich versucht habe:

messageBus.Subscribe("Message/Click",std::bind(&ClickableComponent::OnClick, this)); 

wo die ClickableComponent::OnClick Funktion die erforderliche Signatur hat:

void OnClick(const Message &); 

und die Subscribe-Funktion fügt nur die übergebene Funktion zum Wörterbuch

void Messenger::Subscribe(std::string type, Callback callbackFunction) const 
{ 
    callbackDictionary[type].push_back(callbackFunction); 
} 

(Die push_back wird verwendet, weil es ein Vektor der Rückrufe für jede Art ist)

Der Code scheint mir gut, aber die Zeile:

messageBus.Subscribe("Message/Click", std::bind(&ClickableComponent::OnClick, this)); 

gibt mir den Fehler: picture of the error discription

ich alle möglichen Dinge versucht haben, wie die Messenger Referenz Spedition und Platzhalter verwenden, aber ich habe das Gefühl, dass ich etwas anderes falsch mache. Auch, bessere Idee auf, wie man dieses Botensystem einführt, werden geschätzt ^^

Danke für Ihre Hilfe!

+6

eine Lambda-Funktion statt 'std :: bind' verwenden. – user0042

+0

Verwenden Sie nicht 'für jedes..in' ist es eine Nicht-Standard-Erweiterung und nicht mehr nützlich. Verwende 'for (auto x: xs) {}'. –

Antwort

3

std::bind nicht notwendig, in Ihrem Fall ist, würde Lambda-Funktion ganz gut tun:

messageBus.Subscribe("Message/Click", [this](const Message& msg) { OnClick(msg); }); 

std::bind in bestimmten Fällen von metaprogramming nützlicher ist.

Aber wenn Sie curios genug sind, um zu sehen, wie std::bind verwenden:

messageBus.Subscribe("Message/Click", 
    std::bind(&ClickableComponent::OnClick, this, std::placeholders::_1)); 

hier, wie Sie sehen, verpassten Sie std::placeholders::_1. Ihre Funktorsignatur ist void(const Message&), aber Sie versuchen, eine Mitgliedsfunktion zu speichern, welche Signatur als void(ClickableComponent*, const Message&) angesehen werden kann. Um einige Argumente teilweise anzuwenden (was std::bind tut) müssen Sie Argumente angeben, die Sie binden möchten, und Argumente, die Sie ungebunden lassen.

Lambda wird bevorzugt, weil es in der Regel kurzgeschlossen, flexibler und besser lesbar ist.

Verwandte Themen