0

Im bit new to c++, please let me describe my problem. I have a class called CSubcriber, which main purpose is to execute some callback function, of some type and some number of arguments. For example callbacks can be:

typedef void (*cb1)(void)
typedef int (*cb2)(int, int)
typedef char (*cb3)(int, int, void);

class itself is:

template <class CallbackType>

class CSubscriber {
public:
    CSubscriber();
    virtual ~CSubscriber();
    CallbackType (*m_callback_newWay)(void *params);
    void (*m_callback)(void *params);
    int (*m_callback_int)(void *params);
    void *m_cb_params;
    int execute_cb();
    void *m_params;

    CSubscriber(void (*callback)(void *params), void *cb_params);
    CSubscriber(int (*callback)(void *params), void *cb_params);

};

CSubscriber::CSubscriber(void (*callback)(void *params), void *cb_params){
    m_callback = callback;
    m_cb_params = cb_params;
}

CSubscriber::CSubscriber(int (*callback)(void *params), void *cb_params){
    m_callback_int = callback;
    m_cb_params = cb_params;
}

My main problem is now, how to write constructor, which will handle with all that variable arguments to callback. After constructing object in some particular moment, callback may be fired, for example:

typedef int (*callback)(void *params);
CSubscriber s(callback, params);

or

typedef void (*callback2)(void *params, int arr, char *ptr);
CSubscriber s(callback, params, arr, ptr);

Now, calling

s->m_callback()

I want to execute callback with all arguments which i passed for constructor. I'd like to avoid writing ten different constructors, for each different number of arguments passed to callback function. Is it possible to do ?

Mark Ingram
  • 71,849
  • 51
  • 176
  • 230
JosiP
  • 2,619
  • 5
  • 29
  • 33
  • 1
    if boost or c++11 is an option for you, you may want to look into `boost::bind` (or `std::bind`) - you could pass your constructor a functor – nikolas Jul 15 '13 at 14:52
  • you can use template and have `CallbackType` implement `void operator()()` , `int operator()(int, int)`, & `char operator()(int, int, void)` – andre Jul 15 '13 at 14:55
  • This is a pretty advanced task for C++. To accept and store variable number of parameters of different types, you need a tuple (C++11 or Boost equivalent). See [this](http://stackoverflow.com/questions/7858817/unpacking-a-tuple-to-call-a-matching-function-pointer). You could also have success with lambdas, it's just not clear how exactly you want to store and call the function. – Alexei Sholik Jul 15 '13 at 15:42

1 Answers1

0

Try something like this.

#include <iostream>

using namespace std;

typedef void (*cb1)(void);
typedef int (*cb2)(int, int);
typedef char (*cb3)(int, int, char);

template <class CallbackType>
class CSubscriber
{
public:
    CSubscriber(): fcn1(0), fcn2(0), fcn3(0) {};
    virtual ~CSubscriber(){};

    CSubscriber(cb1 fcn): fcn1(fcn), fcn2(0), fcn3(0), a(), b() {};
    CSubscriber(cb2 fcn, int p1, int p2): fcn1(0), fcn2(fcn), fcn3(0), a(p1), b(p2)  {};

    int execute_cb() {
        if ( fcn1 != 0 ) {
            (*fcn1)();
        }
        if ( fcn2 != 0 ) {
            (*fcn2)(a,b);
        }
    };

protected:
    cb1  fcn1;
    cb2  fcn2;
    cb3  fcn3;

    int a, b;
};

void fcn1() {
    cout << "in fcn1" << endl;
};

int fcn2(int a, int b) {
    cout << "in fcn2, a " << a << ", b " << b << endl;
};

int main()
{
    CSubscriber<int> cs;
    CSubscriber<int> cs1(&fcn1);
    CSubscriber<int> cs2(&fcn2, 1, 100);

    cs.execute_cb();
    cs1.execute_cb();
    cs2.execute_cb();
 }
Yangling
  • 29
  • 2