Zeiger auf eine Methode über typedef
-
Ich versuche gerade, in einer ABC definierte Memberfunktionen als Parameter in einer abgeleiteten Klasse zu übergeben, finde aber keine vernünftige Lösung.
gegeben://WVObject.hpp class WVObject { protected: typedef bool (*EvalFun)(unsigned long); bool evalA (unsigned long id) const; bool evalB (unsigned long id) const; template <class T> T getVal (EvalFun fnctToEval) const { //hier der Zugriff auf die übergebene Methode (*fnctToEval) (i); } public: //... };//WVKnoten.hpp class WVKnoten : public WVObject { } //WVKnoten.cpp void WVKnoten::parse () { //... int res = getVal<float>(evalB); //hier liegt wahrscheinlich der Fehler }Wenn ich das so mache, dann sagt der Compiler
WVKnoten.cpp(21): error C2248: "WVObject::evalB": Kein Zugriff auf protected Member, dessen Deklaration in der WVObject-Klasse erfolgte.
WVKnoten.cpp(21): error C2664: 'T WVObject::getVal<float>(const std::string &,unsigned short,unsigned short,WVObject::EvalFun,bool,unsigned long) const': Konvertierung des Parameters 4 von 'bool (__thiscall WVObject::* )(const std::string &,unsigned long,const std::string &,const std::string &) const' in 'WVObject::EvalFun' nicht möglichIm Internet bin ich auch nicht schlauer geworden. Was mache ich falsch?
-
[Rewind] schrieb:
Im Internet bin ich auch nicht schlauer geworden. Was mache ich falsch?
Du mißachtest den Thread [url=http://www.c-plusplus.net/forum/304133]Den richtigen Code posten: reduziertes compilierbares Beispiel
[/url]
Dann sind sowohlevalA, als auchevalBMemberfunktionen, also mitnichten vom TypEvalFun.Ich glaube das hier koennte eine Lösung sein.
Änderungen markiert.class gadget{ protected: typedef void(gadget::*fp)(); // hier void a(){} void b(){} public: void func(fp p){} }; struct widget : gadget{ gadget g; void func2(){ g.func(&widget::a); // hier } }; int main(){ }Ich verstehe 11.4 [class.protected] dahingehend, dass der nested-name-specifier widget da hin muss(Z.13).
-
Danke, aber durch die Änderungen hat sich nichts an der Ausgabe geändert.
Mir ist aufgefallen, dass du die Funktion nicht über dasimplizite this, sondern über ein Objekt der Basisklasse aufrufst. Hat das irgendeine Auswirkung?
-
[Rewind] schrieb:
Mir ist aufgefallen, dass du die Funktion nicht über dasimplizite this, sondern über ein Objekt der Basisklasse aufrufst. Hat das irgendeine Auswirkung?
Das ist - wie geschrieben - meine Interpretation von 11.4 im C++ Standard.
11.4 Protected member access [class.protected]
1 An additional access check beyond those described earlier in Clause 11 is applied when a non-static data member or non-static member function is a protected member of its naming class (11.2)115 As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class C. If the access is to form a pointer to member (5.3.1), the nested-name-specifier shall denote C or a class derived from C. All other accesses involve a (possibly implicit) object expression (5.2.5). In this case, the class of the object expression shall be C or a class derived from C.[Rewind] schrieb:
Danke, aber durch die Änderungen hat sich nichts an der Ausgabe geändert.
Dann wäre es jetzt wirklich an der Zeit ein minimales Beispiel zu bringen. Meins scheint ja das Problem nicht widerzuspiegeln.
-
https://ideone.com/KqqNKY
Wie gesagt, das Problem könnten Zeile 7 und/oder 27 sein.#include <iostream> using namespace std; class WVObject { protected: typedef bool (*EvalFun)(unsigned long); bool evalA (unsigned long id) const { return true; } bool evalB (unsigned long id) const { return false; } bool test (EvalFun fnctToEval) const { //hier der Zugriff auf die übergebene Methode bool res = (*fnctToEval) (4); return res; } public: virtual void parse() = 0; }; //WVKnoten.hpp class WVKnoten : public WVObject { public: void parse () { cout << test(&WVObject::evalA); } }; int main() { WVKnoten obj; obj.parse(); return 0; }
-
#include <iostream> using namespace std; class WVObject { protected: typedef bool ( WVObject::* EvalFun ) ( unsigned long ) const; // Das hier muss ein Zeiger auf eine Memberfunktion sein bool evalA ( unsigned long id ) const { return true; } bool evalB ( unsigned long id ) const { return false; } bool test ( EvalFun fnctToEval ) { bool res = (this->*fnctToEval)( 4 ); // Hier muss die entsprechende Syntax verwendet werden return res; } public: virtual void parse() = 0; }; class WVKnoten : public WVObject { public: void parse () { cout << test( &WVKnoten::evalA ); /* Es muss WVKnoten sein*/ } }; int main() { WVKnoten obj; obj.parse(); }
-
Super, Arcoth, danke! Problem gelöst.