views:

148

answers:

3

Hello,

I'd like to declare a member function pointer in C++, that returns the same member function pointer type

This doesn't work:

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

Does someone know a solution?

+4  A: 

There's no way to achieve exactly that. In fact, member functions make no difference here: there's no way to declare an ordinary function that returns a pointer to its own function type. The declaration would be infinitely recursive.

In case of an ordinary function you can use the void (*)() type as an "universal" function pointer type (just like void * is often used for data types). For member function pointers that would be void (A::*)() type. You'd have to use reinterpret_cast for that purpose though. However, this usage (a round-trip conversion) happens to be the one when the behavior of reinterpret_cast is defined.

Of course, you'll be forced to use casts to convert the pointer to and from that type. AFAIK, there are elegant template-based solutions with an intermediate temporary template object that does the casting.

You might also want to take a look at this GotW entry.

P.S. Note, that using void * type as an intermediate type for function pointers is prohibited by the language. While such illegal use might appear to be "working" with ordinary function pointers, it has absolutely no chance to work with member function pointers. Member function pointers are normally non-trivial objects with size greater than the size of void * pointer.

AndreyT
A: 

What you're trying to do is not possible - the return type of the function is the type of the function itself, which is not yet known, so it leads to an infinite cycle.

casablanca
+3  A: 

AndreyT references the best answer at GotW #57, so I might as well replicate it here:

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

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

} 
MSN
Funny how so many "it's not possible" answers have disappeared...
Beta