Zeiger auf Memberfunktion mit gleichen Rückgabetyp
-
Hallo zusammen,
ich würde gerne einen Zeiger auf eine Memberfunktion deklarieren,
die genau so einen Zeiger auch wieder zurückliefert.Ist das möglich?
So
class A { public: typedef FncPtr (A::*FncPtr)(); }oder so
class A { public: typedef A::FncPtr (A::*FncPtr)(); }klappt es leider nicht...
Da fehlt mir ja (vermutlich) eine Vorwärtsdeklaration für den Rückgabewert.
Wie mache ich dafür eine Forwärtsdeklaration?
bzw.
Wie krieg ich mein gewünschtes Verhalten hin?Gruß,
CSpille
-
Warum auch immer du das vorhast, so klappts:
A.h:
#ifndef A_H #define A_H #include <iostream> class A; typedef void (A::*fPtr)(); typedef fPtr (A::*fPtr_returns_fPtr)(); class A { public: void foo() { std::cout << "Hello"; } fPtr bar() { return &A::foo; } }; #endifAufruf:
#include "A.h" int main() { A a; fPtr_returns_fPtr foobar = &A::bar; fPtr f = (a.*foobar)(); (a.*f)(); // ruft a.foo() auf }
-
Max0r schrieb:
typedef void (A::*fPtr)(); typedef fPtr (A::*fPtr_returns_fPtr)();Ja nee...
Wie man sowas generell macht, ist mir klar, jedoch soll der Rückgabetyp
von fPtr_returns_fPtr ebenfalls fPtr_returns_fPtr sein.Danke dir trotzdem Max0r!!!
-
CSpille schrieb:
Wie man sowas generell macht, ist mir klar, jedoch soll der Rückgabetyp
von fPtr_returns_fPtr ebenfalls fPtr_returns_fPtr sein.Du läufst hier in eine unendliche Reihe von Rückgaben. Wo soll diese aufhören? Wenn du diese Frage nicht beantworten kannst, dann hast du einen Fehler in deinem Design.
-
SeppJ schrieb:
CSpille schrieb:
Wie man sowas generell macht, ist mir klar, jedoch soll der Rückgabetyp
von fPtr_returns_fPtr ebenfalls fPtr_returns_fPtr sein.Du läufst hier in eine unendliche Reihe von Rückgaben. Wo soll diese aufhören? Wenn du diese Frage nicht beantworten kannst, dann hast du einen Fehler in deinem Design.
Versteh ich nicht...
Klar kann man (theoretisch) eine unendliche Kette kreieren.Nach deiner Argumentation würde sowas dann ja (glaub ich) auch nicht gehen:
class A{ public: A* getA(); };Da hast du dann ja auch eine (potentiell) unendliche Kette..
-
Naja...
Vielleicht ist dieses Beispiel besser:
#include <iostream> #include <vector> template<typename T> void print(T* t){ while(t!=NULL){ std::cout << t->getValue() << std::endl; t = t->getNeighbour(); } } template<typename ElementType> class NeighbourInfo{ public: typedef ElementType element_type; NeighbourInfo(NeighbourInfo<element_type>* n, int value) : neighbour(n), value(value){ } NeighbourInfo<element_type>* getNeighbour(){ return neighbour; } int getValue(){ return value; } private: NeighbourInfo<element_type>* neighbour; int value; }; int main() { NeighbourInfo<int> n1(0,0); NeighbourInfo<int> n2(&n1,1); NeighbourInfo<int> n3(&n2,2); NeighbourInfo<int> n4(&n3,3); NeighbourInfo<int> n5(&n4,4); NeighbourInfo<int> n6(&n5,5); print(&n6); return 0; }Hier wird ja auch eine Kette von Neighbour<int> ineinandergeschachtelt, die
(theoretisch) unendlich werden kann...EDIT:
Alternativ rekursiv:
template<typename T> void print(T* t){ std::cout << t->getValue() << std::endl; print(t->getNeighbour()); }
-
CSpille schrieb:
Da hast du dann ja auch eine (potentiell) unendliche Kette..
Nein, das ist nur beliebig lang, aber trotzdem immer endlich. Bei dem was du vorhast willst du eine Funktion haben, die einen Zeiger auf eine Funktion zurückgibt, die einen Zeiger auf eine Funktion zurückgibt, die einen Zeiger auf eine Funktion zurückgibt, die...
das ist unendlich, weils tatsächlich kein Ende gibt.
-
pumuckl schrieb:
CSpille schrieb:
Da hast du dann ja auch eine (potentiell) unendliche Kette..
Nein, das ist nur beliebig lang, aber trotzdem immer endlich. Bei dem was du vorhast willst du eine Funktion haben, die einen Zeiger auf eine Funktion zurückgibt, die einen Zeiger auf eine Funktion zurückgibt, die einen Zeiger auf eine Funktion zurückgibt, die...
das ist unendlich, weils tatsächlich kein Ende gibt.
Ich glaub ich bin etwas schwer von Begriff ^^
Ich hab das Beispiel etwas abgewandelt, jetzt ist die Kette (der Ring) doch auch
unendlich, oder?#include <iostream> #include <vector> template<typename T> void print(T* t, int depth){ if(depth>0){ std::cout << t->getValue() << std::endl; print(t->getNeighbour(),--depth); } } template<typename ElementType> class NeighbourInfo{ public: typedef ElementType element_type; NeighbourInfo(NeighbourInfo<element_type>* n, int value) : neighbour(n), value(value){ } void setNeighbour(NeighbourInfo<element_type>* n){ neighbour = n; } NeighbourInfo<element_type>* getNeighbour(){ return neighbour; } int getValue(){ return value; } private: NeighbourInfo<element_type>* neighbour; int value; }; int main() { NeighbourInfo<int> n1(0,0); NeighbourInfo<int> n2(&n1,1); n1.setNeighbour(&n2); print(&n1, 1000); return 0; }
-
Viel interessanter wäre doch die Frage, warum du glaubst, sowas benötigen zu müssen.

-
Nexus schrieb:
Viel interessanter wäre doch die Frage, warum du glaubst, sowas benötigen zu müssen.

Als ich diesen Beitrag gelesen habe, mußte ich erstmal schmunzeln

also...
Es war natürlich arg vereinfacht. In Wirklichkeit möchte ich etwas
erzeugen wie:std::vector<std::pair<Info, FncPtr>> (A::*FncPtr)(/*Params*/);Der Rückgabewert ist eine Liste mit Paaren Information und wo geht's weiter
Der Benutzer kriegt dann an eine Funktion alle Möglichkeiten (Rückgabe dieser Funktion)
übergeben und soll anhand der Info entscheiden, was er machen möchte.
Die Funktion gibt dann das entsprechende std::pair (oder nur Funktion-Pointer) zurück.Anhand der Auswahl des Benutzers und der damit verknüpften Funktion
werden dann die weiteren Verlaufsmöglichkeiten kreiert.