Reputation: 4862
Im trying to create a call back by passing a pointer to member functions but am running into all types of issues.
How can i go about implementing such a thing
template<class T> class A{
void (T::*callBackFunction)(int);
public:
void addCallBack(void (T::*callBackFunction)(int)){
void (T::*callBackFunction)(int) = &callBackFunction;
}
void performCallBack(){ //I want this to activate the specified function in class B
callBackFunction(3);
}
};
Class B{
A<B> a1;
A<B> a2;
B(){
a1.addCallBack(&a1CallBack);
a2.addCallBack(&a2CallBack);
}
void a1CallBack(int i){
// do stuff
}
void a2CallBack(int i){
// do stuff
}
};
Upvotes: 0
Views: 2238
Reputation: 31445
If what you really want is a callback function that takes int as a parameter and returns void, you can use boost::function.
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
struct A
{
typedef boost::function1<int, void> func_type;
func_type func;
explicit A( func_type func_ ) :
func( func_ )
{
}
void call( int x )
{
func(x);
}
};
struct B
{
int myVal;
explicit B(int val ) : myVal( val ) {}
void mycall(int x)
{
std::cout << (myVal + x) << std::endl;
}
};
int main()
{
B b(5);
A a( boost::bind( &B::mycall, b, _1 ) );
a.call( 3 );
}
and with any luck it will print 8.
Upvotes: 0
Reputation: 36131
You could do something like this. The virtual base class BaseCB allows B to be totally unaware of the type of C but still invoke the callback.
class BaseCB{
public:
virtual void operator()(int x)=0;
};
template<class ClassT>
class CCallback : public BaseCB {
public:
typedef void(ClassT::* FuncT)(int);
FuncT _fn;
ClassT* _c;
CCallback(ClassT* c, FuncT fn):_fn(fn),_c(c){}
void operator()(int x){
return (_c->*_fn)(x);
}
};
class B {
public:
BaseCB* a;
void invokecb(int n){
(*a)(n);
}
};
class C {
B b;
public:
C(){
b.a = new CCallback<C>(this,&C::cb);
b.invokecb(3);
};
void cb(int n)
{
cout << n;
}
};
C c; // create an instance of c and test the cb mechanism
Upvotes: 3
Reputation: 64283
You need the reference (or a pointer) to the object on which you want to call the method.
I would suggest to create a template base class (template parameters are function return value and parameters), and a template derived class (all base template parameters, plus the object type). The derived class holds the reference to the object and the pointer to the member function.
EDIT:
Maybe something like this (not tested) :
template < typename R, typename T1 >
class CbBase
{
public:
virtual ~CbBase(){}
virtual R call( T1 t1 ) = 0;
};
template < typename O, typename R, typename T1 >
class MemFunPtrCb : public CbBase< R, T1 >
{
public:
MemFunPtrCb( O &obj_, R (O::*memFcPtr_)( T1 t1 ) ) :
obj( obj_ ),
memFcPtr( memFcPtr_ ),
{
}
virtual R call( T1 t1 )
{
obj.memFcPtr( t1 );
}
private:
O &obj;
R (O::*memFcPtr)( T1 t1 );
};
This example is missing :
a function to create MemFuncPtrCb object, this function needs to take a reference to the object, and member function, and return shared_ptr to the appropriate base class
typedefs
Upvotes: 1
Reputation: 76876
Pointers to member function require a pointer to an instance as their first parameter. Read this. The general way to do this is to have the callback function take an extra parameter (usually a void *
) that can represent extra information or context for the callback handler. This could be the pointer to an object to which the callback would be delegated.
Upvotes: 1