代码之家  ›  专栏  ›  技术社区  ›  VincentDM

模板函数,用于对模板化对象执行成员回调,而不提供其实例

  •  0
  • VincentDM  · 技术社区  · 6 年前

    某些上下文。。。

    • 我有一张地图,其中包含对象向量作为值。
    • 每个向量都包含专用类型的对象。
    • 映射的键是表示每种类型的枚举的值, EnumObjType
    • 我收到的事件包含 枚举对象类型 ObjID

    我试图构建一个模板函数来处理任何类型的对象,我的挑战是这些对象ID是通过专门类的方法访问的。为了解决这个问题,我尝试向模板函数中添加一个参数,该参数将被调用以获取 SpecializedObj 的ID。

    模板函数调用如下所示:

    bool processEvent<SpecializedObj>(iEvent, iObjMap, &SpecializedObj::getSpecializedId);
    

    定义:

    template<typename ObjType>
    bool processEvent(MyEvent* iEvent,  ObjMap* iObjMap, std::function<unsigned int(void)> iObjIdCall)
    {
      // Reach the corresponding ObjType vector
      ObjMap::iterator it =  iObjMap->find(iEvent->getObjType());
      std::vector<BaseObject*> wObjVector = it->second;
    
      // Iterate over the vector's range  
      for(BaseObject* wBaseObjPtr : wObjVector)
      {
        // Cast into SpecializedObj
        ObjType* wSpecializedObjPtr = dynamic_cast<ObjType*>(wBaseObjPtr);
    
        // Test dynamic_cast result
        if(!wSpecializedObjPtr) {return false;}
    
        std::function<unsigned int(void)> callback = std::bind(iObjIdCall,*wSpecializedObjPtr);
    
        // Check if the SpecializedObjPtr's ID matches the event's DeviceId
        if(callback() != iEvent->getDeviceId()) {return false;}
    
        // work on SpecializedObj
        // ...
        return true
      }
    

    在我看来,这是一个相当隐晦的错误:

    11>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(514) : error C2664: 'std::_Func_class<_Ret>::_Set' : cannot convert parameter 1 from '_Myimpl *' to 'std::_Func_base<_Rx> *'
    11>        with
    11>        [
    11>            _Ret=const unsigned int
    11>        ]
    11>        and
    11>        [
    11>            _Rx=const unsigned int
    11>        ]
    11>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    11>        C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(514) : see reference to function template instantiation 'void std::_Func_class<_Ret>::_Do_alloc<_Myimpl,_Fret(__thiscall SpecializedObj::* const &)(void) const,_Alloc>(_Fty,_Alloc)' being compiled
    11>        with
    11>        [
    11>            _Ret=const unsigned int,
    11>            _Fret=const unsigned int,
    11>            _Alloc=std::allocator<std::_Func_class<const unsigned int>>,
    11>            _Fty=const unsigned int (__thiscall SpecializedObj::* const &)(void) const
    11>        ]
    11>        C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(514) : see reference to function template instantiation 'void std::_Func_class<_Ret>::_Do_alloc<_Myimpl,_Fret(__thiscall SpecializedObj::* const &)(void) const,_Alloc>(_Fty,_Alloc)' being compiled
    11>        with
    11>        [
    11>            _Ret=const unsigned int,
    11>            _Fret=const unsigned int,
    11>            _Alloc=std::allocator<std::_Func_class<const unsigned int>>,
    11>            _Fty=const unsigned int (__thiscall SpecializedObj::* const &)(void) const
    11>        ]
    11>        C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(514) : see reference to function template instantiation 'void std::_Func_class<_Ret>::_Reset_alloc<_Fret,SpecializedObj,std::allocator<_Ty>>(_Fret (__thiscall SpecializedObj::* const )(void) const,_Alloc)' being compiled
    11>        with
    11>        [
    11>            _Ret=const unsigned int,
    11>            _Fret=const unsigned int,
    11>            _Ty=std::_Func_class<const unsigned int>,
    11>            _Alloc=std::allocator<std::_Func_class<const unsigned int>>
    11>        ]
    11>        C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(514) : see reference to function template instantiation 'void std::_Func_class<_Ret>::_Reset_alloc<_Fret,SpecializedObj,std::allocator<_Ty>>(_Fret (__thiscall SpecializedObj::* const )(void) const,_Alloc)' being compiled
    11>        with
    11>        [
    11>            _Ret=const unsigned int,
    11>            _Fret=const unsigned int,
    11>            _Ty=std::_Func_class<const unsigned int>,
    11>            _Alloc=std::allocator<std::_Func_class<const unsigned int>>
    11>        ]
    11>        C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(675) : see reference to function template instantiation 'void std::_Func_class<_Ret>::_Reset<const unsigned int,SpecializedObj>(_Fret (__thiscall SpecializedObj::* const )(void) const)' being compiled
    11>        with
    11>        [
    11>            _Ret=const unsigned int,
    11>            _Fret=const unsigned int
    11>        ]
    11>        C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(675) : see reference to function template instantiation 'void std::_Func_class<_Ret>::_Reset<const unsigned int,SpecializedObj>(_Fret (__thiscall SpecializedObj::* const )(void) const)' being compiled
    11>        with
    11>        [
    11>            _Ret=const unsigned int,
    11>            _Fret=const unsigned int
    11>        ]
    11>        C:\MyProject\ObjUpdater.cpp(29) : see reference to function template instantiation 'std::function<_Fty>::function<const unsigned int(__thiscall SpecializedObj::* )(void) const>(_Fx &&)' being compiled
    11>        with
    11>        [
    11>            _Fty=const unsigned int (void),
    11>            _Fx=const unsigned int (__thiscall SpecializedObj::* )(void) const
    11>        ]
    11>        C:\MyProject\ObjUpdater.cpp(29) : see reference to function template instantiation 'std::function<_Fty>::function<const unsigned int(__thiscall SpecializedObj::* )(void) const>(_Fx &&)' being compiled
    11>        with
    11>        [
    11>            _Fty=const unsigned int (void),
    11>            _Fx=const unsigned int (__thiscall SpecializedObj::* )(void) const
    11>        ]
    

    当我以前使用回调时,我总是知道它将与哪个对象实例相关联,所以我会将它作为函数参数传递给 std::bind(&Foo::func, fooObj) 但这似乎对我不起作用。

    编辑: 我正在使用Visual Studio 2012 v110工具集

    1 回复  |  直到 6 年前
        1
  •  1
  •   max66    6 年前

    当我以前使用回调时,我总是知道它将与哪个对象实例相关联,所以我会将它作为函数参数传递给 std::bind(&Foo::func, fooObj) 但这似乎对我不起作用。

    如果 processEvent() 接收 iObjIdCall 作为 std::function<unsigned int(void)> ,当您尝试绑定它并保存 std::bind() 生成相同类型的对象

    std::function<unsigned int(void)> callback
        = std::bind(iObjIdCall,*wSpecializedObjPtr);
    

    你把编译器搞糊涂了。

    尝试定义 processEvent() 接收指向方法的指针,而不是 std::function ; 某物作为

    template <typename ObjType>
    bool processEvent (MyEvent* iEvent,  ObjMap* iObjMap, ObjType::*iObjIdCall)
    

    如果我没记错语法的话。