2010-07-02 10 views
7

Ich mag würde ein Mitglied Funktionszeiger in C++ deklarieren, welche die gleiche Member-Funktion Zeigertyp gibtMitglied Funktionszeiger, die gleiche Art von Elementfunktion Zeiger zurückgibt

Dies funktioniert nicht:

class MyClass { 
public: 
     typedef FunctionPtr (MyClass::*FunctionPtr)(); 
} 

Kennt jemand eine Lösung?

+0

Ich würde gerne Gebrauch 'mem_fun_ref' sagen, aber ich kann nicht sehen, wie. Gute Frage. – wheaties

+1

nicht schon wieder ... Warum wollen alle das machen? Ich habe noch nie etwas gebraucht, das so nah wäre. –

+0

@David: Ich bin bei dir dabei. Ich erinnere mich daran, Member-Pointer _once_ in 15 Jahren Programmierung in C++ zu verwenden. – sbi

Antwort

5

Es gibt keine Möglichkeit, genau das zu erreichen. Tatsächlich machen Member-Funktionen hier keinen Unterschied: Es gibt keine Möglichkeit, eine gewöhnliche Funktion zu deklarieren, die einen Zeiger auf ihren eigenen Funktionstyp zurückgibt. Die Deklaration wäre unendlich rekursiv.

Im Falle einer normalen Funktion können Sie den Typ void (*)() als "universellen" Funktionszeigertyp verwenden (genau wie void * wird oft für Datentypen verwendet). Für Mitgliedsfunktionszeiger wäre das void (A::*)() Typ. Sie müssen reinterpret_cast für diesen Zweck verwenden. Diese Verwendung (eine Round-Trip-Konvertierung) ist jedoch diejenige, bei der das Verhalten von reinterpret_cast definiert ist.

Natürlich werden Sie gezwungen sein, Umwandlungen zu verwenden, um den Zeiger zu und von diesem Typ zu konvertieren. AFAIK, gibt es elegante Template-basierte Lösungen mit einem temporären Template-Zwischenobjekt, das das Casting übernimmt.

Sie können auch einen Blick auf diese GotW entry werfen.

P.S. Beachten Sie, dass die Verwendung des Typs void * als Zwischentyp für Funktionszeiger von der Sprache verboten ist. Während eine solche illegale Verwendung mit gewöhnlichen Funktionszeigern zu funktionieren scheint, hat sie absolut keine Chance, mit Mitgliedsfunktionszeigern zu arbeiten. Mitgliedsfunktionszeiger sind normalerweise nicht-triviale Objekte mit einer Größe, die größer ist als die Größe von void * Zeiger.

0

Was Sie versuchen, ist nicht möglich - der Rückgabetyp der Funktion ist der Typ der Funktion selbst, der noch nicht bekannt ist, also zu einem unendlichen Zyklus führt.

5

AndreyT verweist auf die beste Antwort auf GotW #57, so könnte ich auch replizieren es hier:

class MyClass { 
public: 
     struct FunctionPtrProxy; 
     typedef FunctionPtrProxy (MyClass::*FunctionPtr)(); 

     struct FunctionPtrProxy 
     { 
       FunctionPtrProxy(FunctionPtr pp) : p(pp) { } 
       operator FunctionPtr() { return p; } 
       FunctionPtr p; 
     } 

} 
+2

Lustig wie so viele "es ist nicht möglich" Antworten sind verschwunden ... – Beta

+0

Ich konnte das Beispiel auf GoW # 57 zu arbeiten. Aber wenn ich eine Member-Funktion zur obigen Klasse hinzufüge, die nur sich selbst zurückgibt, die nicht kompiliert werden kann (gcc error: argument vom Typ 'MyClass :: FunctionPtrProxy (MyClass ::)()' stimmt nicht mit 'MyClass :: FunctionPtrProxy' überein). @MSN könntest du ein Beispiel mit der obigen Klasse angeben, wo du eine Memberfunktion hast, die sich selbst zurückgibt und wo sie kompiliert, danke :) –