tags:

views:

121

answers:

1

Hello, I have such situation in boost and 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 */ }
};

This code throws error for the file with 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&]
+2  A: 

InputSystem::keyPressed expects a slot (a callable object), but GameApplication's ctor only passes a pointer to member. Try something like:

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

Edit: This works for me (compiles and prints "key pressed with 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);
}
Éric Malenfant
Now it builds. But slot have never been called.
Ockonal
I don't forget about calling singnal. Somewhere in **InputSystem** I do: `SigKeyPressed(110);`
Ockonal
@Ockonal: You mean `mSigKeyPressed(110);`, not `SigKeyPressed(110);`, right?
Éric Malenfant
Yeah, `mSigKeyPressed(localEvent.Key);`
Ockonal
@Ockonal: I added full code to my answer.
Éric Malenfant
Okay. Thank you. Will work under this more.
Ockonal