|
Boost : |
From: Jesse Jones (jejones_at_[hidden])
Date: 2000-11-16 21:26:54
>> Or, alternatively, you can assign a function with two arguments to a
>> callback with one if the second argument has a default value.
>>
>I don't know how you are going to do this, the default value doesn't appear
>to travel with the function. If you know how, please let me know.
You have to treat the function as a black box (ie you can't expload it and
pick out the argument types). I've appended a stripped down version of the
code I use below. I think it supports all the requirements mentioned so far
except allowing a function that returns a value to be assigned to a
callback that returns void. I had a nice meta-programming fix for this, but
I couldn't get it past CW 5.3 so in the real code I specialized
FunctorCallback1 and MethodCallback1 for void RETURN_TYPE's.
template <class RETURN_TYPE, class ARG1>
class Callback1 {
public:
typedef RETURN_TYPE result_type;
typedef ARG1 argument_type;
public:
~Callback1() {if (mCallback != nil)
mCallback->RemoveReference();}
Callback1() : mCallback(nil) {}
template <class FUNCTION>
Callback1(FUNCTION function) : mCallback(new
Internals::FunctorCallback1<FUNCTION, RETURN_TYPE, ARG1>(function)) {}
template <class OBJECT, class METHOD>
Callback1(OBJECT* object, METHOD method) : mCallback(new
Internals::MethodCallback1<OBJECT, METHOD, RETURN_TYPE, ARG1>(object,
method)) {}
// plus more stuff like copy ctor, assignment operator, operator==, etc
public:
RETURN_TYPE operator()(ARG1 arg1) const {return
mCallback->Call(arg1);}
private:
Internals::BaseCallback1<RETURN_TYPE, ARG1>* mCallback;
};
namespace Internals {
template <class RETURN_TYPE, class ARG1>
class BaseCallback1 : public ReferenceCountedMixin {
public:
virtual ~BaseCallback1() {}
BaseCallback1() {}
public:
virtual RETURN_TYPE Call(ARG1 arg1) const = 0;
};
template <class FUNCTOR, class RETURN_TYPE, class ARG1>
class FunctorCallback1 : public BaseCallback1<RETURN_TYPE, ARG1> {
public:
FunctorCallback1(FUNCTOR functor) : mFunctor(functor) {}
virtual RETURN_TYPE Call(ARG1 arg1) const {return mFunctor(arg1);}
private:
FUNCTOR mFunctor;
};
template <class OBJECT, class METHOD, class RETURN_TYPE, class ARG1>
class MethodCallback1 : public BaseCallback1<RETURN_TYPE, ARG1> {
public:
MethodCallback1(OBJECT* object, METHOD method)
{ASSERT(object != nil); ASSERT(method != nil); mObject = object; mMethod =
method;}
virtual RETURN_TYPE Call(ARG1 arg1) const {return
(mObject->*mMethod)(arg1);}
private:
OBJECT* mObject;
METHOD mMethod;
};
} // namespace Internals
-- Jesse
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk