Map mit std::function
-
Hallo,
ich schreibe alten C++ mit vielen Funktionpointer um auf C++11. Jetzt habe ich das Problem Funktionpointer von Memberfunktionen in einer Map zu speichern.
Hier meine bisherige Lösung
#include <functional> #include <iostream> #include <map> using namespace std; struct Para { int value; }; class Base { }; class Derived1 : public Base { public: void command11(Para para) { cout << "Command 11: " << para.value << endl; } void command12(Para para) { cout << "Command 12: " << para.value << endl; } }; class Derived2 : public Base { public: void command21(Para para) { cout << "Command 21: " << para.value << endl; } void command22(Para para) { cout << "Command 22: " << para.value << endl; } }; int main() { map<int, std::function<void(Para)>> m; m[11] = [=](Para p) {Derived1 d; d.command11(p);}; m[12] = [=](Para p) {Derived1 d; d.command12(p);}; m[21] = [=](Para p) {Derived2 d; d.command21(p);}; m[22] = [=](Para p) {Derived2 d; d.command22(p);}; int code = 21; auto it = m.find(code); if (it != end(m)) it->second({ 5 }); cin.get(); return 0; }Mich stören die Zeilen mit
m[11] = [=](Para p) {Derived1 d; d.command11(p);};. Kann man das eleganter machen, z.B. mit einer Funktion, die ich die Adresse der Klasse und die Adresse der Funktion angebe?
Sowas wiem[11] = makeFunction(&Derived1(), &Derived1::command11);?
Dieser Code soll nur mein Problem verdeutlichen. Die Klassen werden später viel komplexer sein.
-
Was du da zeigst braucht keine Klassen/Objekte, da du nirgends den Objekzustand berücksichtigst. Das könnte man mit einfachen Funktionen lösen. Solltest du das Beispiel zu sehr vereinfacht haben, wirst du ja irgendwann den geänderten Zustand benutzen wollen, d.h. irgenwie mussst du dir die Objekte merken. Davon hängt alles weitere ab.
-
Innerhalb der verschiedenen Commands wird auf gemeinsame Daten innerhalb der Klasse zu gegriffen z.B. (wieder total vereinfacht)
class Base { }; class Derived1 : public Base { private: int value; public: void command11(Para para) { value += para.value; cout << "Command 11: " << para.value << endl; } void command12(Para para) { value -= para.value; cout << "Command 12: " << para.value << endl; } };So dass das Auslagern der Commands in Funktionen nicht möglich ist.
-
Dann muss es doch etwas in der Art sein
Derived1 d1; m[11] = [&](Para p) { d1.command11(p);}; m[12] = [&](Para p) { d1.command12(p);}; Derived2 d2; m[21] = [&](Para p) { d2.command21(p);}; m[22] = [&](Para p) { d2.command22(p);};Und natürlich müssen d1 und d2 noch existieren, wenn die Funktionen aufgerufen werden.
-
Ok,
auf die Lösung war ich auch schon gekommen. Und klar die Instanzen von Derived1 und Derived2 müssen existieren.
-
Wenn du eh std::function verwendest, kannst du auch std::bind verwenden um auch member funktionen in ein std::function zu packen.