问题描述
,它看起来像我没有提供足够的细节。
Expanding on this question, it looks like I did not provide enough detail.
我有一个对象 CallbackObject
对象实例以及调用函数的信息以及调用时传递的参数。
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() ;
}
我遇到的唯一问题是如果 objectType
是一个指针类型,那么(obj。* fcnPtr)
失败,因为它应该真的读取((obj)。* fcnPtr)
或(obj-> * fcnPtr)
if obj is a pointer。
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.
一个解决方案,其中我定义另一个 CallbackObject类如下:
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 ) ;
}
} ;
但这是最好的crufty,并且难以在最坏的情况下使用,如果有人使用这个代码,他们将不得不创建一个
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.
有什么办法吗?
推荐答案
这里是一个示例帮助函数,假设void返回,一个参数,并且不需要处理多个间接级别:
Here's an example helper function, assuming void return, one argument, and no need to handle more than one level of indirection:
template <typename T, typename F, typename A>
inline void invoke(T& obj, F func, const A& arg)
{
(obj.*func)(arg);
}
template <typename T, typename F, typename A>
inline void invoke(T* obj, F func, const A& arg)
{
(obj->*func)(arg);
}
如果需要处理多个级别的间接,第二函数:
If you need to handle more than one level of indirection, you can replace the second function with this:
template <typename T, typename F, typename A>
inline void invoke(T* obj, F func, const A& arg)
{
invoke(*obj, func, arg);
}
这将递归地剥离间接级别,直到你结束了可以调用你的成员函数。
This will recursively strip off levels of indirection until you end up with something that you can invoke your member function on.
然后你可以写 exec()
函数:
void exec()
{
invoke(obj, fcnPtr, arg1);
}
这篇关于参考水平第2部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!