本文介绍了参考水平第2部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

,它看起来像我没有提供足够的细节。

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部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 20:43