Expanding on this question, it looks like I did not provide enough detail.
I have an object called CallbackObject that is designed to contain an object instance, and the information of what function to invoke, and the parameters to pass at invokation time.
template <typename objectType,
typename memberFunctionPtrType,
typename memberFcnArg1Type>
struct CallbackObject1
{
objectType obj ;
memberFunctionPtrType fcnPtr ;
memberFcnArg1Type arg1 ;
CallbackObject1(objectType iObj,
memberFunctionPtrType iFcnPtr,
memberFcnArg1Type iArg1 )
{
obj = iObj ;
fcnPtr = iFcnPtr ;
arg1 = iArg1 ;
}
void exec()
{
(obj.*fcnPtr)( arg1 ) ;
}
} ;
Example of use:
struct Point
{
float x,y ;
void print( int numTimes )
{
for( int i = 0 ; i < numTimes ; i++ )
printf( "%f %f\n", x, y ) ;
}
} ;
typedef void (Point::* PointPrintFcnType)( int ) ;
int main()
{
Point p ;
p.x=p.y=1;
CallbackObject1<Point, PointPrintFcnType, int> ocall( p, &Point::print, 5 );
ocall.exec() ;
}
The only problem I’m having is if objectType is a pointer type, then (obj.*fcnPtr) fails, since it should really read ( (*obj).*fcnPtr) or (obj->*fcnPtr) if obj is a pointer.
Now I have one solution, where I define another CallbackObject class like so:
template <typename pObjectType,
typename memberFunctionPtrType,
typename memberFcnArg1Type>
struct CallbackPObject1
{
pObjectType obj ;
memberFunctionPtrType fcnPtr ;
memberFcnArg1Type arg1 ;
CallbackPObject1(pObjectType iObj,
memberFunctionPtrType iFcnPtr,
memberFcnArg1Type iArg1 )
{
obj = iObj ;
fcnPtr = iFcnPtr ;
arg1 = iArg1 ;
}
void exec()
{
(obj->*fcnPtr)( arg1 ) ;
}
} ;
But this is crufty at best, and difficult to use at worst, if someone else is using this code, they will have to create a different kind of Callback object if the object type being used is actually a pointer.
Is there any way around this?
Here’s an example helper function, assuming void return, one argument, and no need to handle more than one level of indirection:
If you need to handle more than one level of indirection, you can replace the second function with this:
This will recursively strip off levels of indirection until you end up with something that you can invoke your member function on.
You can then write your
exec()function like so: