[gelöst] Funktionszeiger in Template-Funktionen innerhalb einer Klasse...



  • Hallo,

    ist wahrscheinlich für jeden C++-Profi nur eine Kleinigkeit, aber ich suche mir hier die Finger wund und die Web- und Forum-Suche gibt immer kleine Beispiele, welche mir aber nicht weiter helfen, weil ich eine komplexere Konstelation habe, als die Zweizeiler-Beispiele. Und ich schaffe es auch gerade nicht, das gelesene so anzuwenden, dass es mein Problem löst.

    Ich erarbeite mir derzeit wieder mal meine C++-Grundlagen, weil ich jetzt einige Jahre nichts in C++ gemacht habe. Und gleichzeitig versuche ich meine Basis-Funktionen so zu schreiben, dass mein Sohn (4te Klasse) auch damit arbeiten kann. Ich hab somit natürlich viele Template-Klassen mit Template-Funktionen und wenn ich mal alle Parameter sowie Template- und Define-Definitionen wegkürze, komm sowas bei raus:

    class b {
    public:
    	static void funcC() {}
    };
    
    class a {
    
    public:
    	template<class _func>
    	void doAny(_func usFunc) {
    		usFunc();
    	}
    
    	void funcA() {}
    	void funcB() {}
    
    	void test() {
    		doAny(funcA); // HIER, Zeile 25
    		doAny(a::funcB); // HIER, Zeile 26
    		doAny(b::funcC);
    	}
    };
    

    Und jetzt die Frage:
    Wie muss ich das schreiben, dass mir die Zeilen mit "HIER" gekennzeichnet funktionieren. Ich erhalte immer diese Meldungen:

    1>sample.cpp(25): error C3867: "a::funcA": Keine Standardsyntax; "&" zum Erstellen eines Verweises auf das Member verwenden
    1>sample.cpp(25): error C2672: "a::doAny": keine übereinstimmende überladene Funktion gefunden
    1>sample.cpp(26): error C3867: "a::funcB": Keine Standardsyntax; "&" zum Erstellen eines Verweises auf das Member verwenden
    1>sample.cpp(26): error C2672: "a::doAny": keine übereinstimmende überladene Funktion gefunden
    

    Wohl unnötig zu sagen, dass ein "&"-Zeichen auch die Lösung nicht ergibt.
    Also mein Problem mit der Verständnis ist:
    Bei einer static-Function einer anderen Klasse klappt es, aber wenn ich auf mich selbst "ver-zeigern" will, dann geht es nicht.

    Hilfööö und Danke.


  • Mod

    &a::funcB sollte gehen. Zumindest was den direkten Fehler hier angeht, denn das ist die korrekte Syntax, um einen Zeiger auf eine Memberfunktion (oder allgemein: Jede Art von Member) zu erhalten. Das führt dann aber direkt zum nächsten Problem, denn ich habe nicht umsonst "Zeiger auf Memberfunktion" anstatt "Funktionszeiger" gesagt. In deiner doAny-Funktion versuchst du direkt den Parameter usFunc aufzurufen, als wäre er ein funktionsartiges Objekt. Eine (nicht-statische) Memberfunktion braucht aber ein Objekt einer Klasse, aber du gibst hier nicht an, welches Objekt das sein soll (tatsächlich hast du kein einziges a-Objekt in deinem Programm). Daher wirst du dann eine Fehlermeldung in der Art von

    error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘usFunc'
    

    erhalten.
    Wenn man das mal ganz ohne Templates und Zeiger macht, dann hast du praktisch dies hier versucht:

    class foo
    {
    public:
      void some_func() {}
    };
    
    int main()
    {
      foo::some_func();
    }
    

    Das funktioniert schließlich auch nicht, stattdessen müsste es so etwas wie

    int main()
    {
      foo f;
      f.some_func();
    }
    

    sein. Du hast in deinem Code kein Äquivalent für das f aus meinem Beispiel.

    Daher gibt es drei Möglichkeiten:
    * Die Funktion funcA braucht gar kein Objekt der Klasse. Du benutzt dann entweder Klassen falsch, als eine Art Namespace; oder die Methode hätte static sein sollen.
    * Oder das ist richtig so, und es gibt in deinem Programm ein bestimmtes Objekt, für das du die funcA aufrufen möchtest. In dem Fall gibt es viele Möglichkeiten, die Kombination aus funcA und dem Objekt an die doAny zu übergeben. Das einfachste wäre wohl, sie mittels std::bind zu einem funktionsartigen Objekt zu bündeln.
    * Oder es ist alles richtig, wie in Fall 2, aber das Objekt, für das funcA ausgeführt werden soll, ist das Objekt für das doAny aufgerufen wurde. In dem Fall rufst du die Funktion einfach für das this in doAny auf. Falls doAny sowohl mit Memberzeigern als auch mit freien Funktionen zurecht kommen soll, musst du eine Spezialisierung für diese zwei Fälle machen



  • Hallo,
    Danke. std::bind() ist das, was ich brauche. Es sind natürlich Funktionen, die auf Member-Variablen zugreifen. Also "static" kann ich nicht verwenden. Aber mit bind erhalte ich das, was ich brauche. Dein beschriebener Falle 3 tritt bei mir nicht ein, aber verstanden (und getestet) habe ich das auch.

    Immerhin ist das erste Problem gelöst. Ist zwar ein neues da, aber das bekomme ich schon hin. 😉


Log in to reply