2016-09-22 3 views
2

Ich bin versucht, einen Beobachter Muster in c zu schreiben ++ so habe ich eine Karte, die Ereignisnamen enthält -> Vektor von Callback-Funktionenein Element aus einem Vektor von std entfernen :: function

Die Callback-Funktionen gespeichert sind, in einem Vektor als

std::function<void(void *)> 

so sieht die Karte wie

std::unordered_map<std::string, std::vector<std::function<void(void *)>>> 

ich Zuhörer auf den Vektor hinzufügen und empfangen und Ereignisbenachrichtigungen reagieren. Mein Problem ist mit dem Implementieren von Trennen.

Also std :: function's kann nicht verglichen werden, also löschen/entfernen ist out, also wollte ich den Vektor suchen und manuell vergleichen.

fand ich, dass this question hatte Erfolg mit immer Zugriff auf die zugrunde liegende Zeiger std :: Funktion :: Ziel, aber ich kann das nicht verwenden, da ich std :: bind bin mit dem Rückruf zu initialisieren:

std::function<void(void *)> fnCallback = std::bind(&wdog::onBark, this, std::placeholders::_1) 

Ich möchte nur die zugrunde liegende Memberfunktion ptrs vergleichen, oder sogar einen Vergleich mit dem zugrunde liegenden Objekt ptr, dem die Elementfunktion zugeordnet ist. Gibt es irgendeinen Weg?

Ich möchte das Mitglied fn ptr in einem Objekt vermeiden Verpackung, die einen Hash enthält, obwohl es so aussieht, muss ich diesen Weg gehen könnte ...

+2

Können Sie ein Beispiel veröffentlichen, wie Sie Elemente aus der Karte hinzufügen/entfernen möchten? – Holt

+0

Es scheint mir, dass Sie bereits die Antwort wissen ... :-) – skypjack

+1

Sie können es nicht wirklich tun, ohne auch einen Zeiger auf das fragliche Objekt zu speichern, um es als Schlüssel zu verwenden. Mein Impl verwendet weak_ptr und überprüft die Sammlung, um abgelaufene() vor dem Absenden des Ereignisses zu entfernen. Attach ist (shared_from_this(), & class :: member), detach ist (shared_from_this()). – Robinson

Antwort

2

Wenn ich das tue, ich ein Token zurückgeben zum Abhörcode.

Mein übliches Muster ist eine weak_ptr<function<sig>> im Broadcaster zu haben, und das Token ist ein shared_ptr<void> (zum gespeicherten schwachen ptr).

Bei der Ausstrahlung filtere ich tote Ziele aus und sende dann. Ziele löschen sich durch einfaches Löschen, Zerstören oder anderweitiges Verwerfen ihres Tokens. Ein Vektor von Token in ihrer Instanz ist ein vernünftiger Weg, wenn sie sich niemals abmelden wollen.

Wenn man das nie ausstrahlt, kann das dazu führen, dass alte tote Ressourcen unnötig herumhängen, also in einem öffentlichen Rahmen möchte ich vielleicht etwas mit besseren Garantien haben. Aber es ist leicht, leicht und schnell sonst.

+0

können Sie bitte einen Beispiel-Code von dem, was oben genannten? –

+0

@segme http://stackoverflow.com/a/34400239/1774667 ist eine vorherige Skizze auf SO. Ich weiß nicht, ob es das Beste ist, was ich öffentlich gepostet habe oder nicht, aber es sollte dir die Idee geben. – Yakk

Verwandte Themen