2014-03-01 16 views
6

So habe ich mehrere Methoden mit verschiedenen Argumenten:C++ Warteschlange von Funktionen

class c; 

void c::foo1(int a) { 

} 

void c::foo2(int a, int b) { 

} 

Wie habe ich eine Warteschlange/Vektor dieser Funktionen? Es muss nicht unbedingt ein std :: function-Objekt sein, aber ich brauche eine Möglichkeit, die Ausführung von Funktionen in die Warteschlange zu stellen.

+4

Wie planen Sie herauszufinden, wie Sie jeden anrufen? – chris

+0

Die Verwendung eines [Befehlsmusters] (http://en.wikipedia.org/wiki/Command_pattern) kann eine Option sein. –

+0

Was möchten Sie mit der Funktionsliste machen? Was ist Ihre Absicht, diese Funktionsliste zu erstellen? – Fox

Antwort

9

Ihre Frage ist ein wenig vage, aber wenn man schon das Zielobjekt und die Argumente auf den Anruf kennen zu der Zeit Sie die Funktionen in die Warteschlange einfügen, können Sie eine Warteschlange von parameterlos lambdas verwenden:

std::deque<std::function<void()>> q; 
c x; 
q.push_back([&x] { x.foo1(1); }); 
q.push_back([&x] { x.foo2(2,3); }); 
// ... some time later we might want to execute the functions in the queue ... 
while (!q.empty()) 
{ 
    q.front()(); 
    q.pop_front(); 
} 
+0

Wenn Sie keine parameterlosen Lambdas haben, wie würden Sie dann die Parameter weiterleiten? – serup

0

Die kurze Antwort ist, dass Sie nicht können. Ein halbwegs einfacher Weg wäre, alle Funktionen eine Liste oder einen Vektor von Argumenten zu nehmen, wobei jedes Argument ein int ist, oder wenn Sie mehr Argumenttypen unterstützen müssen, eine Boost-Variante. Dann können alle Funktionen die gleiche Signatur haben und ihre Implementierungen müssen ihre Argumente entpacken.

Wenn sich alle Methoden in einer einzelnen Klasse befinden, können Sie sie in einer Liste als einfache Zeiger auf Elementfunktionen speichern. Das wäre effizienter als das Speichern in std :: -Funktionen und klarer, wenn Sie damit durchkommen.

0

Ihre Absicht ist unklar. Um die Antwort von @ JohnZwicnk zu erweitern ...

Eine Funktionssignatur enthält ihren Rückgabetyp, ihren Klassenobjekttyp (wenn es sich um eine Klassenmemberfunktion handelt) und ihre Parameter - was bedeutet, dass es keinen einfachen Weg gibt, einen gemeinsamen Namen zu erstellen 'Funktionstyp'.

Das bedeutet nicht, dass Sie nicht demselben Objekttyp verschiedene Arten von Funktionen zuweisen können - boost :: function und boost :: mem_function sind zwei Beispiele dafür, wie Sie einer Funktion eine generische Funktion mit Parametern zuweisen können übergeben Sie es herum, bevor es aufgerufen wird.

Wenn Sie nur nacheinander jede Funktion aufrufen möchten, ohne sich um den Typ zu kümmern, sehen Sie sich functors oder die oben erwähnte boost :: mem_function an. In beiden Fällen können Sie den Funktionsaufruf entweder binden oder zuweisen und die Auswertung der Funktion für später verzögern.