Generalized Callbacks in C++ using TR1

Recently, I had situation where a class (say called B) aggregated a class (say A). Class A would fire messages during a computation and I wanted to be able to subscribe to these messages in class B by passing a pointer to member function . The syntax of pointer to member functions is a little strange and seen often. I also wanted arbitrary global functions or other classes to be valid subscribers.

TR1 provides two useful classes to achieve this std::tr1::function which allows us to create to create a call wrapper . And std::tr1:bind which allows for us to bind to an object.

The below code implements the scenario described in the first paragraph.

#include <iostream>

#include <functional>

#include <vector>

 

using namespace std;

using namespace std::tr1;

 

void foo(int i)

{

  cout << "foo " << i << endl;

}

 

 

class A

public:

  typedef function< void(int) > Delegate;

  void addSubscriber(Delegate func)

  {

    _subscribers.push_back(func);

  }

 

  void action()

  {

    for(vector<Delegate>::iterator it = _subscribers.begin(); it!=_subscribers.end(); ++it)

    {

      (*it)(10);

    }

  }

 

private:

  vector< Delegate > _subscribers;

};

 

 

class B

{

  A  a;

  void callback(int i)

  {

    cout << "B::callback() " << i << endl;

  }

 

public:

  B(int i)

  {

  }

 

  void connect()

  {     

    A::Delegate memfunc = std::tr1::bind(&B::callback,*this,std::tr1::placeholders::_1);

    a.addSubscriber(memfunc);

 

    A::Delegate globalfunc = &foo;

    a.addSubscriber(globalfunc);   

  }

 

  void action()

  {

    a.action();

  }

 

private:

  B()

  {

  }

 

};

 

 

int main()

{

  B b(10);

  b.connect();

  b.action();

  return 0;

}

 

Tested on Window using Visual Studio 2008, GCC should no be a problem (might just need the includes changing).

This entry was posted by Edobashira. Bookmark the permalink.

3 thoughts on “Generalized Callbacks in C++ using TR1”

Leave a Reply

Note: only a member of this blog may post a comment.