参考水平第2部分
Reference level part 2
扩展到这个问题,我似乎没有提供足够的细节。
我有一个名为CallbackObject
的对象,它被设计为包含一个对象实例、要调用的函数的信息以及在调用时要传递的参数。
模板<typename对象类型,typename memberFunctionPtrType,typename成员FcnArg1Type>结构回调对象1{objectType obj;memberFunctionPtr类型fcnPtr;memberFcnArg1类型arg1;回调对象1(对象类型iObj,memberFunctionPtr类型iFcnPtr,成员FcnArg1类型iArg1){obj=iObj;fcnPtr=iFcnPtr;arg1=iArg1;}void exec(){(obj.*fcnPtr)(arg1)}};
使用示例:
结构点{浮动x,y;无效打印(int numTimes){for(int i=0;i<numTimes;i++)printf("%f%f\n",x,y);}};typedef void(点::*PointPrintFcType)(int);int main(){点p;p.x=p.y=1;回调对象1<点,PointPrintFcType,int>ocall(p,&Point::打印,5);ocall.exec();}
我遇到的唯一问题是,如果objectType
是指针类型,那么(obj.*fcnPtr)
会失败,因为如果obj是指针,它应该真正读取( (*obj).*fcnPtr)
或(obj->*fcnPtr)
。
现在我有了一个解决方案,其中我定义了另一个回调对象类,如下所示:
模板<typename pObjectType,typename memberFunctionPtrType,typename成员FcnArg1Type>结构体CallbackPObject1{pObjectType obj;memberFunctionPtr类型fcnPtr;memberFcnArg1类型arg1;回调PObject1(pObjectType iObj,memberFunctionPtr类型iFcnPtr,成员FcnArg1类型iArg1){obj=iObj;fcnPtr=iFcnPtr;arg1=iArg1;}void exec(){(obj->*fcnPtr)(arg1)}};
但这往好里说很粗糙,往坏里说很难使用,如果其他人正在使用这段代码,如果使用的对象类型实际上是指针,他们将不得不创建不同类型的回调对象。
有办法解决这个问题吗?
这里有一个示例辅助函数,假设返回void,一个参数,并且不需要处理多个间接级别:
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);
}
如果您需要处理多个级别的间接,您可以将第二个函数替换为:
template <typename T, typename F, typename A>
inline void invoke(T* obj, F func, const A& arg)
{
invoke(*obj, func, arg);
}
这将递归地剥离间接级别,直到您最终得到可以在上调用成员函数的东西
然后,您可以这样编写exec()
函数:
void exec()
{
invoke(obj, fcnPtr, arg1);
}
将诸如boost::function
之类的多态函数对象与诸如boost::bind
之类的产生函数的函数结合使用。这是一个非常优越的解决方案-天才发生在函子产生时,而不是在调用它时,并且任何可以用正确签名调用的函数对象都可以被调用。
好的,对上一个问题应用"重载"方法,我得到
模板<typename对象类型,typename memberFunctionPtrType,typename成员FcnArg1Type>结构体CallbackObject1:公共回调{objectType obj;objectType*pObj;memberFunctionPtr类型fcnPtr;memberFcnArg1类型arg1;回调对象1(对象类型iObj,memberFunctionPtr类型iFcnPtr,成员FcnArg1类型iArg1){obj=iObj;pObj=0;fcnPtr=iFcnPtr;arg1=iArg1;}回调对象1(对象类型*iObj,memberFunctionPtr类型iFcnPtr,成员FcnArg1类型iArg1){pObj=iObj;fcnPtr=iFcnPtr;arg1=iArg1;}void exec(){if(pObj)(pObj->*fcnPtr)(arg1);其他的(obj.*fcnPtr)(arg1);}};
使用
typedef void(点::*PointPrintFcType)(int);点p;p.x=p.y=1;回调对象1<点,PointPrintFcType,int>ocall(p,&Point::打印,5);ocall.exec();回调PObject1<Point*,PointPrintFcType,int>ocallP(&p,&Point::打印,2);ocallP.exec();
它工作得还可以,但内部并不像我希望的那样干净。
相关文章:
- QTableView:endMoveRows在模型中重置水平页眉大小
- QScrollArea:由垂直滚动条引起的水平滚动条
- 如何将部分流作为参数传递
- 有没有办法修改'operator->',以便'z->im'返回复数的虚部
- 通过水平滚动条更改标签
- 如何删除部分类?
- 如何在c ++中以一行(水平)打印两个文件的数据?如给定的.这两种形式来自两个不同的文本文件
- O2优化水平中断程序工作
- 如何只链接到柯南包中的部分库?
- 在 SDL 中水平减小静态图像进度条
- 在高通六边形处理器的word32上执行水平求和的最快方法是什么
- 无法打印用户填充的部分数组的反面
- 使用类型特征的部分类专用化
- 将 CRTP 与部分类专用化结合使用?
- 为什么 C++17 标准没有带来部分类模板参数扣除?
- C++17 中的部分类模板参数推导
- 水平排列 QMenu 项目
- 将水平滚动条添加到控制台
- QListWidget 水平滚动条会导致选择消失在视野之外
- 如何在可滚动的 QTableWidget 中有一个冻结的水平标题?