ich versuche mit C++ 11 einen Event-Container zu bauen (à la C#). Über operator += kann man einen Event-Handler zum Container hinzufügen, und per operator -= kann man einen Event-Handler aus dem Container entfernen. Gespeichert weden die Event-Handler in einem std::vector<std::function<...>>.
Um einen Event-Handler zu entfernen muss ich natürlich irgendwie std::functions auf Gleichheit prüfen. Bekannterweise haben std::functions wegen irgendeinem, mir unbekannten Problem aber keine Vergleichsoperatoren. Also gehe ich über std::function::target<T>() und std::function::target_type(). Das Problem ist, dass ich mittlerweile so verwirrt bin, dass ich mich dabei komplett unsicher fühle. Ist diese Vorgehensweise okay, oder verursacht die Probleme, die ich grad nicht sehe?
Im folgenden der Code, den ich gerade zum Testen benutze. Der funktioniert, aber ist er, bezüglich des Funktionsvergleichs auch problemfrei...?!
WARNUNG: Selbst wenn sich herausstellen sollte, dass die Funktionsvergleiche im Code unten okay sind, so ist zu bemerken das das TEventContainer-Template noch nicht fertig implementiert ist. Wenn zum Beispiel ein Event-Handler sich selbst entfernt, dann kracht es im Karton. Also bitte nicht blind benutzen.
Code: Alles auswählen
#include <vector>
#include <functional>
#include <iostream>
// Typ für einen Beispiel Event-Handler.
using MyEventHandler = std::function<void (void * pParam1, void * pParam2)>;
// Event Container
template <class _TEventHandler>
class TEventContainer
{
public:
TEventContainer<_TEventHandler> & operator -= (_TEventHandler eventHandler)
{
size_t numEventHandlers = m_eventHandlers.size();
for (size_t i = 0; i < numEventHandlers; i++)
{
// Hier der Funktionsvergleich
if (m_eventHandlers[i].target<_TEventHandler>() == eventHandler.target<_TEventHandler>()
&& m_eventHandlers[i].target_type() == eventHandler.target_type())
{
m_eventHandlers.erase(m_eventHandlers.begin() + i);
break;
}
}
return *this;
}
TEventContainer<_TEventHandler> & operator += (_TEventHandler eventHandler)
{
m_eventHandlers.push_back(eventHandler);
return *this;
}
public:
template <class ... _TArgs>
void operator () (_TArgs ... args)
{
size_t numEventHandlers = m_eventHandlers.size();
for (size_t i = 0; i < numEventHandlers; i++)
{
m_eventHandlers[i](args ...);
}
}
private:
std::vector<_TEventHandler> m_eventHandlers;
};
// Test-Code
int main(int argc, char * argv[])
{
MyEventHandler lambdaHandler = [] (void * pParam1, void * pParam2)
{
std::cout << "called" << std::endl;
};
TEventContainer<MyEventHandler> eventContainer;
eventContainer += lambdaHandler;
eventContainer += lambdaHandler;
eventContainer -= lambdaHandler;
eventContainer += lambdaHandler;
eventContainer -= lambdaHandler;
// Alle Event-Handler aufrufen
eventContainer(nullptr, nullptr);
return 0;
}