Look up "functors". They are wrappers that take care for pointers to member functions. I believe the gamedev article "Enginuity, part 2" (or part 3) has an elaborate description on them.
The code below is from my codebase. It's rather old, and has a few quirks to make it compile under VC++ (VC++ doesn't allow partial specialisation in templates which causes all kinds of troubles here).
BTW, If I were to guess what the problem is, it'd be the ampersands before the returning of the function pointer in getfunc().
Plus your functions don't have a return type before your function definitions.
I can't try it out ATM because I haven't installed my compiler on this PC yet.
Code:
/** The Functor object is the parent of the ObjFunctor.
This because this way we make it possible this way to fill containers with Functors to multiple objecttypes
The virtual functions are meant for easy access and the ability to actually make lists and vectors of functors. The ObjFunctor has more specialised functions.
*/
class Functor
{
public:
virtual void call()=0;
virtual void call(int i)=0; //sometimes one might want to pass a variable to the function.
//We limit ourselves to an integer for the sake of simplicity
};
/** This is the ObjFunctor, the heart of our functor. The object holds a templated pointer to an object and can have a certain return type for the function.
Creating an objectFunctor: ObjFunctor<myreturntype, myclass, myreturntype (myclass::*)(param1)> functorname(objectpointer, functionpointer);
Calling a functor:
functorname(); //no return type, no arguments
functorname.callWithReturn(); //with return type, no arguments
functorname(param1, param2); //with return type and two arguments
*/
template<typename ReturnType, class TClassType, typename funcType>
class ObjFunctor : public Functor
{
protected:
//typedef ReturnType (TClassType::*funcType)();
//funcType func;
funcType func; //pointer to the function
//funcType nonparamfunc;
void (TClassType::*nonparamfunc0)(); //pointer to a function with no parameters used for mass-storage
void (TClassType::*nonparamfunc1)(int); //pointer to a function with one parameter used for mass-storage
TClassType* obj; //pointer to the actual object
public:
typedef ReturnType return_type; //ability to get the return type from the functor
/** This constructor takes the pointer to the object and the pointer to the function that is going to be called
@param o The pointer to the object
@param f The pointer to the function
*/
ObjFunctor(TClassType* o, funcType f)
{
obj = o; func = f;
nonparamfunc0 = 0;
nonparamfunc1 = 0;
}
/** This constructor is supposed to take care of Functors that should be stored in a container
@param o Pointer to the object we're gonna call
@param f The pointer to the function
@param i Integer that indicates how many parameters we are passing through. Can be 0 or 1.
*/
ObjFunctor(TClassType* o, funcType f, int i)
{
obj = o;
if (i==0)
{
nonparamfunc0 = (void (TClassType::*)())f; //cast the function pointer to a function pointer with no arguments
nonparamfunc1 = 0;
}
else if (i==1)
{
nonparamfunc0 = 0;
nonparamfunc1 = (void (TClassType::*)(int))f; //cast the function pointer to a function pointer with one argument
}
else
{
nonparamfunc0 = 0;
nonparamfunc1 = 0;
}
}
/** This function is supposed to allow storage of functors in a container.
However there are a few issues regarding this part
*/
void call()
{
if(nonparamfunc0) //we should do a check here because I can understand it's very possible to make mistakes here
(obj->*nonparamfunc0)();
}
void call(int i)
{
if(nonparamfunc1) //we should do a check here because I can understand it's very possible to make mistakes here
(obj->*nonparamfunc1)(i);
}
/** The overloaded () operator allows for easy calling of the Functor */
ReturnType operator ()()
{
return (obj->*func)();
}
/** The overloaded () operator allows for easy calling of the Functor
@param a1 Templated value, can be anything
*/
template<typename Arg1>
ReturnType operator()(Arg1 a1)
{
return (obj->*func)(a1);
}
/** The overloaded () operator allows for easy calling of the Functor
@param a1 Templated value, can be anything
@param a2 Templated value
*/
template<typename Arg1, typename Arg2>
ReturnType operator()(Arg1 a1, Arg2 a2)
{
return (obj->*func)(a1,a2);
}
/** The overloaded () operator allows for easy calling of the Functor
@param a1 Templated value, can be anything
@param a2 Templated value
@param a3 Templated value
*/
template<typename Arg1, typename Arg2, typename Arg3>
ReturnType operator()(Arg1 a1, Arg2 a2, Arg3 a3)
{
return (obj->*func)(a1,a2,a3);
}
//for more arguments this list has to be expanded to the likeness of the previous overloaded operators
//
};
template<typename ReturnType, typename funcType>
class GlobalFunctor : public Functor
{
private:
funcType func; //pointer to the function
void (*nonparamfunc0)(); //pointer to a function with no parameters used for mass-storage
void (*nonparamfunc1)(int); //pointer to a function with one parameter used for mass-storage
public:
/** This constructor takes the pointer to the function that is going to be called
@param f The pointer to the function
*/
GlobalFunctor(funcType f)
{
func = f;
nonparamfunc0 = 0;
nonparamfunc1 = 0;
}
/** This constructor is supposed to take care of Functors that should be stored in a container
@param f The pointer to the function
@param i Integer that indicates how many parameters we are passing through. Can be 0 or 1.
*/
GlobalFunctor(funcType f, int i)
{
if (i==0)
{
nonparamfunc0 = (void (*)())f; //cast the function pointer to a function pointer with no arguments
nonparamfunc1 = 0;
}
else if (i==1)
{
nonparamfunc0 = 0;
nonparamfunc1 = (void (*)(int))f; //cast the function pointer to a function pointer with one argument
}
else
{
nonparamfunc0 = 0;
nonparamfunc1 = 0;
}
}
void call()
{
if(nonparamfunc0) //we should do a check here because I can understand it's very possible to make mistakes here
(nonparamfunc0)();
}
void call(int i)
{
if(nonparamfunc1) //we should do a check here because I can understand it's very possible to make mistakes here
(nonparamfunc1)(i);
}
/** The overloaded () operator allows for easy calling of the Functor */
ReturnType operator ()()
{
return (func)();
}
/** The overloaded () operator allows for easy calling of the Functor
@param a1 Templated value, can be anything
*/
template<typename Arg1>
ReturnType operator()(Arg1 a1)
{
return (func)(a1);
}
/** The overloaded () operator allows for easy calling of the Functor
@param a1 Templated value, can be anything
@param a2 Templated value
*/
template<typename Arg1, typename Arg2>
ReturnType operator()(Arg1 a1, Arg2 a2)
{
return (func)(a1,a2);
}
/** The overloaded () operator allows for easy calling of the Functor
@param a1 Templated value, can be anything
@param a2 Templated value
@param a3 Templated value
*/
template<typename Arg1, typename Arg2, typename Arg3>
ReturnType operator()(Arg1 a1, Arg2 a2, Arg3 a3)
{
return (func)(a1,a2,a3);
}
//for more arguments this list has to be expanded to the likeness of the previous overloaded operators
//
};