pointer auf member functions mappen
-
Hallo an alle!
Ich habe leider niergendwo eine Antwort auf folgendes Problem finden können. Vielleicht kann jemand von euch mir helfen.Folgende Problemstellung:
Ich habe eine Abstrakte Basisklasse, die aber eine funktion zur Verfügung stellt mit der ich die eigenschaften der jeweiligen abgeleiteten Klassen auflisten kann und anhang des Schlüssels die entsprechende Funktion für die jeweilige eigenschaft aufrufen kann.Hier die sehr vereinfachte Variante ohne Vererbung damit man das Problem besser sehen kann.
class B { public: int foo1() { return 1; } int foo2() { return 2; } }; typedef int (B::*__func_ptr)(); class A { private: std::map<std::string, __func_ptr> m_prop_map; ... ... public: A() { m_prop_map["func1"] = &B::foo1(); m_prop_map["func2"] = &B::foo2(); } virtual const std::map<std::string, __func_ptr> listProperties() { return m_prop_map; } } int main() { B b; A a; // Wenn man die funktionen aus der map benutzen möchte muss man sich der // folgenden kryptischen Syntax bedienen. const std::map<std::string, __func_ptr> m = a.listProperties(); int i1 = (a.*m["func1"])(); int i2 = (a.*m["func1"])(); // was sehr unschön ist std::sout << i1 << " " << i2 << std::endl; return 0; }Anstatt von disen Aufrufen
int i1 = (a.*m["func1"])(); int i2 = (a.*m["func1"])();möchte ich folgendes haben:
int i1 = m["func1"]; int i2 = m["func1"];Also habe ich mir gedacht, schreib doch eine wrapper, der den Aufruf
(a.*m["func1"])();intern ausführt.
Der Ansatz sieht dann so aus:
(Die Klasse B und der typdef für den Funktionspointer sieht wie in dem oberen listing aus)class FuncWrap : public std::unary_function<std::string, __func_ptr> { private: B m_a; __func_ptr m_fp; public: FuncWrap(B b, __func_ptr fp) { m_b = b; m_fp = m_fp; } int operator()() { return (m_b.*m_fp)(); } }; class A { public: std::map<std::string, std::unary_function<std::string, __func_ptr> > m_prop_map; A() { m_prop_map;["func1"] = FuncWrap(B(), &B::func1); m_prop_map;["func2"] = FuncWrap(B(), &B::func2); } virtual const std::map<std::string, std::unary_function<std::string, __func_ptr> listProperties() { return m_prop_map; } };Nun mache ich den gewünschten aufruf in der main:
int main() { A c; const std::map<std::string, __func_ptr> m = a.listProperties(); int i1 = m["func1"]; int i2 = m["func1"]; std::sout << i1 << " " << i2 << std::endl; return 0; }und kriege leider einige Compiler Fehler. Für die Aufrufe wie oben sieht die fehlermeldung so aus:
Building file: ../src/test.cpp Invoking: GCC C++ Compiler g++ -I/ ... /src/include -O0 -g3 -p -pg -Wall -c -fmessage-length=0 -osrc/test.o ../src/test.cpp ../src/test.cpp: In function 'int main()': ../src/test.cpp:96: error: cannot convert 'std::unary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int (A::*)()>' to 'int' in initialization ../src/test.cpp:97: error: cannot convert 'std::unary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int (A::*)()>' to 'int' in initialization make: *** [src/test.o] Fehler 1Was eigentlich klar ist, da ich funktionapointer zu int konvertieren möchte;
Für den fall, dass der Aufruf so aussieht:
int i1 = m["func1"](); int i2 = m["func1"]();folgende fehlermeldung:
make -k all Building file: ../src/test.cpp Invoking: GCC C++ Compiler g++ -I/ ... /src/include -O0 -g3 -p -pg -Wall -c -fmessage-length=0 -osrc/test.o ../src/test.cpp ../src/test.cpp: In function 'int main()': ../src/test.cpp:96: error: no match for call to '(std::unary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int (A::*)()>) ()' ../src/test.cpp:97: error: no match for call to '(std::unary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int (A::*)()>) ()' make: *** [src/test.o] Fehler 1 make: Das Target »all« wurde wegen Fehlern nicht aktualisiert. Build complete for project ...Ich hoffe ich konnte verdeutlichen, wo das Problem liegt. Wenn jemand einen Lösungsvorschlag hätte wäre das super.
Danke in Voraus.