2015-09-23 8 views
0

У меня есть класс ...с использованием зОго :: функции в станде :: Карта

#include <map> 
#include <boost/function.hpp> 

enum class ECmd { one, two, three }; 

class C 
{ 
public: 

    void Command(ECmd e) 
    { 
     auto pos = m_fnCmd.find(e); 

     if (pos != m_fnCmd.end()) 
     { 
      // call the function 
      (pos->second)(this); 
     } 
     else 
     { 
      printf("no command!\n"); 
     } 
    } 

protected: 
    using fnCmd = boost::function<void(C*)>; 
    using fnCmdMap = std::map<ECmd, fnCmd>; 

    static const fnCmdMap m_fnCmd; 

    // the command functions 
    void One() { printf("one.\n"); } 
    void Two() { printf("Two.\n"); } 
    void Three() { printf("Three.\n"); } 
}; 

const C::fnCmdMap C::m_fnCmd = 
{ 
    {std::make_pair(ECmd::one, &C::One)}, 
    {std::make_pair(ECmd::two, &C::Two)}, 
    {std::make_pair(ECmd::three, &C::Three)}, 
}; 

который демонстрирует технику я использую для команд на основе обработки идентификаторов. Этот код работает очень хорошо, однако, когда я меняю класс на использование std :: function вместо boost :: function, который он не может скомпилировать - не нравится инициализация C :: m_fnCmd.

Сообщение об ошибке:

1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(506): error C2664: 'void std::_Func_class<_Ret,C *>::_Set(std::_Func_base<_Ret,C *> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,C *> *' 
1>   with 
1>   [ 
1>    _Ret=void 
1>   ] 
1>   Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,C *>::_Do_alloc<_Myimpl,_Fret(__thiscall C::* const &)(void),_Alloc>(_Fty,_Alloc)' being compiled 
1>   with 
1>   [ 
1>    _Ret=void 
1> ,   _Fret=void 
1> ,   _Alloc=std::allocator<std::_Func_class<void,C *>> 
1> ,   _Fty=void (__thiscall C::* const &)(void) 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,C *>::_Do_alloc<_Myimpl,_Fret(__thiscall C::* const &)(void),_Alloc>(_Fty,_Alloc)' being compiled 
1>   with 
1>   [ 
1>    _Ret=void 
1> ,   _Fret=void 
1> ,   _Alloc=std::allocator<std::_Func_class<void,C *>> 
1> ,   _Fty=void (__thiscall C::* const &)(void) 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,C *>::_Reset_alloc<_Fret,C,,std::allocator<std::_Func_class<_Ret,C *>>>(_Fret (__thiscall C::* const)(void),_Alloc)' being compiled 
1>   with 
1>   [ 
1>    _Ret=void 
1> ,   _Fret=void 
1> ,   _Alloc=std::allocator<std::_Func_class<void,C *>> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,C *>::_Reset_alloc<_Fret,C,,std::allocator<std::_Func_class<_Ret,C *>>>(_Fret (__thiscall C::* const)(void),_Alloc)' being compiled 
1>   with 
1>   [ 
1>    _Ret=void 
1> ,   _Fret=void 
1> ,   _Alloc=std::allocator<std::_Func_class<void,C *>> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,C *>::_Reset<void,C,>(_Fret (__thiscall C::* const)(void))' being compiled 
1>   with 
1>   [ 
1>    _Ret=void 
1> ,   _Fret=void 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,C *>::_Reset<void,C,>(_Fret (__thiscall C::* const)(void))' being compiled 
1>   with 
1>   [ 
1>    _Ret=void 
1> ,   _Fret=void 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\utility(157) : see reference to function template instantiation 'std::function<void (C *)>::function<_From>(_Fx &&)' being compiled 
1>   with 
1>   [ 
1>    _From=void (__thiscall C::*)(void) 
1> ,   _Fx=void (__thiscall C::*)(void) 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\utility(157) : see reference to function template instantiation 'std::function<void (C *)>::function<_From>(_Fx &&)' being compiled 
1>   with 
1>   [ 
1>    _From=void (__thiscall C::*)(void) 
1> ,   _Fx=void (__thiscall C::*)(void) 
1>   ] 
1>   c:\projects\test\fntest\fntest.cpp(60) : see reference to function template instantiation 'std::pair<const _Kty,_Ty>::pair<ECmd,void(__thiscall C::*)(void),void>(std::pair<ECmd,void (__thiscall C::*)(void)> &&)' being compiled 
1>   with 
1>   [ 
1>    _Kty=ECmd 
1> ,   _Ty=C::fnCmd 
1>   ] 
1>   c:\projects\test\fntest\fntest.cpp(60) : see reference to function template instantiation 'std::pair<const _Kty,_Ty>::pair<ECmd,void(__thiscall C::*)(void),void>(std::pair<ECmd,void (__thiscall C::*)(void)> &&)' being compiled 
1>   with 
1>   [ 
1>    _Kty=ECmd 
1> ,   _Ty=C::fnCmd 
1>   ] 
1> 
+2

, что это сообщение об ошибке? –

+2

'std :: function' отлично работает с использованием GCC: http://melpon.org/wandbox/permlink/UIH8HupaFEyRa8bz –

ответ

1

Он работает с GCC и Clang (см комментарий Джонатана). Для того, чтобы заставить его работать в VS2013, вы можете добавить зЬй :: mem_fn() вокруг указателей на функции-члены:

const C::fnCmdMap C::m_fnCmd = 
{ 
    {std::make_pair(ECmd::one, std::mem_fn(&C::One))}, 
    {std::make_pair(ECmd::two, std::mem_fn(&C::Two))}, 
    {std::make_pair(ECmd::three, std::mem_fn(&C::Three))}, 
}; 

См VS2013 std::function with member function

+0

Спасибо за то, что прочитал std :: mem_ * функции, которые я думаю ... – RobinI