Проблема с буст-сигналами - PullRequest
1 голос
/ 16 июня 2010

У меня такая ситуация в boost и C ++:

// Somewhere:
typedef boost::signals2::signal<void (int KeyCode)> SigKeyPressed;
typedef SigKeyPressed::slot_type SigKeyPressedType;

class InputSystem
{
   private:
      static SigKeyPressed mSigKeyPressed;
   public:
      static boost::signals2::connection keyPressed(const SigKeyPressedType &slot);
};

boost::signals2::connection InputSystem::keyPressed(const SigKeyPressedType& slot)
{
    // I tried:
    return mSigKeyPressed.connect(boost::bind(&slot, this, _1);
    // Or this:
    return mSigKeyPressed.connect(slot);
}

class GameApplication
{
   public:
      GameApplication() { InputSystem::keyPressed(&GameApplication::onKeyPressed); }
      void onKeyPressed(int KeyCode) { /* do something */ }
};

Этот код выдает ошибку для файла с GameApplication :

/usr/include/boost/function/function_template.hpp: In static member function ‘static void boost::detail::function::function_void_mem_invoker1<MemberPtr, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with MemberPtr = void (GameApplication::*)(sf::Event::KeyEvent&), R = void, T0 = sf::Event::KeyEvent&]’:
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
/usr/include/boost/function/function_template.hpp:913:60:   instantiated from ‘void boost::function1<R, T1>::assign_to(Functor) [with Functor = void (GameApplication::*)(sf::Event::KeyEvent&), R = void, T0 = sf::Event::KeyEvent&]’
/usr/include/boost/function/function_template.hpp:722:7:   instantiated from ‘boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<InputIterator>::value>::value, int>::type) [with Functor = void (GameApplication::*)(sf::Event::KeyEvent&), R = void, T0 = sf::Event::KeyEvent&, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<InputIterator>::value>::value, int>::type = int]’
/usr/include/boost/function/function_template.hpp:1064:16:   instantiated from ‘boost::function<R(T0)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<InputIterator>::value>::value, int>::type) [with Functor = void (GameApplication::*)(sf::Event::KeyEvent&), R = void, T0 = sf::Event::KeyEvent&, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<InputIterator>::value>::value, int>::type = int]’
/usr/include/boost/function/function_template.hpp:1105:5:   instantiated from ‘typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<InputIterator>::value>::value, boost::function<R(T0)>&>::type boost::function<R(T0)>::operator=(Functor) [with Functor = void (GameApplication::*)(sf::Event::KeyEvent&), R = void, T0 = sf::Event::KeyEvent&, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<InputIterator>::value>::value, boost::function<R(T0)>&>::type = boost::function<void(sf::Event::KeyEvent&)>&]’
/usr/include/boost/signals2/detail/slot_template.hpp:137:9:   instantiated from ‘void boost::signals2::slot1<R, T1, SlotFunction>::init_slot_function(const F&) [with F = void (GameApplication::*)(sf::Event::KeyEvent&), R = void, T1 = sf::Event::KeyEvent&, SlotFunction = boost::function<void(sf::Event::KeyEvent&)>]’
/usr/include/boost/signals2/detail/slot_template.hpp:81:9:   instantiated from ‘boost::signals2::slot1<R, T1, SlotFunction>::slot1(const F&) [with F = void (GameApplication::*)(sf::Event::KeyEvent&), R = void, T1 = sf::Event::KeyEvent&, SlotFunction = boost::function<void(sf::Event::KeyEvent&)>]’
src/Core/GameApplication.cpp:14:82:   instantiated from here
/usr/include/boost/function/function_template.hpp:225:11: error: no match for call to ‘(boost::_mfi::mf1<void, GameApplication, sf::Event::KeyEvent&>) (sf::Event::KeyEvent&)’
/usr/include/boost/bind/mem_fn_template.hpp:160:7: note: candidates are: R boost::_mfi::mf1<R, T, A1>::operator()(T*, A1) const [with R = void, T = GameApplication, A1 = sf::Event::KeyEvent&]
/usr/include/boost/bind/mem_fn_template.hpp:179:7: note:                 R boost::_mfi::mf1<R, T, A1>::operator()(T&, A1) const [with R = void, T = GameApplication, A1 = sf::Event::KeyEvent&]

1 Ответ

2 голосов
/ 16 июня 2010

InputSystem::keyPressed ожидает слот (вызываемый объект), но ctor GameApplication передает только указатель на член. Попробуйте что-то вроде:

  GameApplication() 
  {
     InputSystem::keyPressed(bind(&GameApplication::onKeyPressed, this, _1));
  }

Редактировать : Это работает для меня (компилирует и печатает "клавишу, нажатую с 110"):

#include <boost/signals2.hpp>
#include <boost/bind.hpp>
#include <iostream>

typedef boost::signals2::signal<void (int KeyCode)> SigKeyPressed;
typedef SigKeyPressed::slot_type SigKeyPressedType;

class InputSystem
{
   private:
      static SigKeyPressed mSigKeyPressed;
   public:
      static boost::signals2::connection keyPressed(const SigKeyPressedType &slot);
      static void DoSignal(int KeyCode) {mSigKeyPressed(KeyCode);}
};

boost::signals2::connection InputSystem::keyPressed(const SigKeyPressedType& slot)
{
    return mSigKeyPressed.connect(slot);
}

SigKeyPressed InputSystem::mSigKeyPressed;

class GameApplication
{
   public:
       GameApplication() { InputSystem::keyPressed(boost::bind(&GameApplication::onKeyPressed, this, _1)); }
       void onKeyPressed(int KeyCode) { std::cout << "key pressed with " << KeyCode << std::endl; }
};

int main()
{
    GameApplication g;       
    InputSystem::DoSignal(110);
}
...