C++ member function pointer, boost::signals

混江龙づ霸主 提交于 2019-12-04 16:49:56
Guy Sirton

You would typically use boost bind:

foo.Register_SignalFunction(boost::bind(&OtherFoo::OnSignal, this));

What's going on here? :-)

The connect method of the signal takes a functor. That is an object that implements the () operator. bind takes function pointers (either to free functions or member functions) and returns a functor with the right signature.

Also see here:

Complete example using Boost::Signals for C++ Eventing

and here:

how boost::function and boost::bind work

To disconnect a signal store the return value from connect into a:

boost::signals::connection

And then call the disconnect method on that.

Typically you'll either do:

void Register_SignalFunction(const boost::function<void()> &slot) {
    signal += slot;
}

Or, as an inline function:

template<typename T>
void Register_SignalFunction(T &slot) {
    signal += slot;
}

The latter may be slightly more efficient by removing the layer of indirection boost::function has - but only assuming boost::signal doesn't use boost::function internally (which it is likely to). So use whichever one you prefer, really.

I got it working after trying a lot, here's the code:

GraphicsDeviceManager
{
  private:
      typedef boost::signal<void ()> DeviceLost;
      DeviceLost deviceLost;

  public:
      Register_DeviceLostHandler(const boost::function<void ()> &handler)
      {
          deviceLost.connect(slot);
      }
      Unregister_DeviceLostHandler(const boost::function<void ()> &handler)
      {
          //deviceLost.disconnect(slot); 
      }
}

class GameBase
{
  private:
    GraphicsDeviceManager* graphics;

   public:
       GameBase()
       {
          graphics = new GraphicsDeviceManager();
          graphics->Register_DeviceLostHandler(boost::bind(&GameBase::OnDeviceLost, this));
       }
       void OnDeviceLost()
       {
           //do some stuff
       }
}

well this code works as it should be, with one exception, if I unccomment the deviceLost.disconnect(handler) statement, I receive compilation errors like: error C266 "boost::operator ==": 4 overloads have similar conversions.

So, why is this happening? Do you know any other way to accomplish what I'm trying?

In case anyone wants a full example:

#include <iostream>
#include <boost/signals2/signal.hpp>
#include <boost/bind.hpp>
#include <boost/optional/optional_io.hpp>

#define registerEvent_(A)   registerEvent(boost::bind(A, this, _1, _2))

struct A
{
    typedef boost::signals2::signal<int (int &, int &)> EventSignal;
    typedef EventSignal::slot_type SlotType;

    void registerEvent(const SlotType & slot);
    void triggerAll(int& a1, int& a2);

    EventSignal signal_;
};

void A::registerEvent(const SlotType & slot) { signal_.connect(slot); }
void A::triggerAll(int& a1, int& a2) {std::cout << signal_(a1, a2) << "\n";}

struct B : public A
{
    B();
    int myFunc(int& a1, int& a2);
};

B::B() {
#ifdef WITHMACRO
    registerEvent_(&B::myFunc);
#else
    registerEvent(boost::bind(&B::myFunc, this, _1, _2));
#endif
}
int B::myFunc(int& a1, int& a2) { return a1 + a2 + 1; }

int main()
{
    int a1 = 2;
    int a2 = 3;
    B b;
    b.triggerAll(a1, a2);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!