Boost logo

Boost Users :

Subject: [Boost-users] Generically connecting a signal to a member function
From: Chris Stankevitz (chrisstankevitz_at_[hidden])
Date: 2012-10-18 19:12:48


Hello,

I wrote a function called "Connect" which generically connects a
signal to a member function. The pseudo-code for this function is:

void Connect(Signal, MemberFunction, pClass)
{
  Signal.connect(Signal::slot_type(MemberFunction, pClass));
}

Problem: I had to create "overloads" for different number of signal
arguments. This was somewhat expected and we see it in boost with
things like boost::bind. What I did not expect was that each of my
overloads had to have a different name. This is because all overloads
have the same function signature: one signal, one member function, one
class pointer.

Question: Is there a way to write a generic "Connect" that handles
signals of different number of arguments? If overloading is involved,
can it be done like bind such that all overloads have the same name?

Below is my solution that exhibits the "problem" I described above.

Thank you for your help,

Chris

===

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

//-------------------------------------
// Connect0
//
// Generically connect a member
// function to a signal producing zero
// arguments.
//-------------------------------------
template <
  class TASignal,
  class TAMemberFunction,
  class TAClass>
void Connect0(
  TASignal& Signal,
  TAMemberFunction MemberFunction,
  TAClass* pClass)
{
  typedef typename TASignal::slot_type TDSlot;

  TDSlot Slot(MemberFunction, pClass);

  Signal.connect(Slot);
}

//-------------------------------------
// Connect0
//
// Generically connect a member
// function to a signal producing one
// arguments.
//-------------------------------------
template <
  class TASignal,
  class TAMemberFunction,
  class TAClass>
void Connect1(
  TASignal& Signal,
  TAMemberFunction MemberFunction,
  TAClass* pClass)
{
  typedef typename TASignal::slot_type TDSlot;

  TDSlot Slot(MemberFunction, pClass, _1);

  Signal.connect(Slot);
}

//-------------------------------------
// Connect2
//
// Generically connect a member
// function to a signal producing two
// arguments.
//-------------------------------------
template <
  class TASignal,
  class TAMemberFunction,
  class TAClass>
void Connect2(
  TASignal& Signal,
  TAMemberFunction MemberFunction,
  TAClass* pClass)
{
  typedef typename TASignal::slot_type TDSlot;

  TDSlot Slot(MemberFunction, pClass, _1, _2);

  Signal.connect(Slot);
}

//-------------------------------------
//-------------------------------------
struct TCClass
{
    void f0() {}
    void f1(int) {}
    void f2(int, int) {}
};

//-------------------------------------
//-------------------------------------
int main()
{
  boost::signals2::signal<void()> Signal0;
  boost::signals2::signal<void(int)> Signal1;
  boost::signals2::signal<void(int, int)> Signal2;

  TCClass Class;

  Connect0(Signal0, &TCClass::f0, &Class);
  Connect1(Signal1, &TCClass::f1, &Class);
  Connect2(Signal2, &TCClass::f2, &Class);

  Signal0();
  Signal1(1);
  Signal2(2, 2);

  return 0;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net