Please ignore if the title didn't make sense; this is probably only interesting to a minority of people!
I've been doing some experiments tonight around pointers to member functions (among other things). The main problem is C++ really doesn't handle them at all well, and to get the functionality I wanted to allow people to register member functions as handlers in the current library, I really had to pull of some horrible tricks (even had to bring out memcpy in the trampoline :(.
However, I think i've finally hit on a better way based on reframing the problem slightly, and just want to give people a chance to shout if for some reason this new approach wouldn't work for them. I haven't worked through everything so there may be some hidden gotchas, but it is much simpler and gives basically the same functionality so I am very likely to make this change assuming there are no blockers.
Here is the explanation:
Currently, any class that accepts registration of static functions and member functions basically has something like the following:
void attach(void (*function)(void));
template <class T>
void attach(T *object, void (T::*member)(void));
Whilst the interface is ok(ish), the implementation for this has to jump through hoops. It basically comes from the problem that pointers to member functions are not guaranteed to be alike. It also means new code generated for every type of member function attached (it is a template), which carries through to classes that expose it further up the chain.
Ok, so what I propose is that the basic static attach can also provide a void* pointer to some data, that is provided back on callback. And as soon as it does that, everything gets much easier! (hindsight is a wonderful thing!). So now for member functions, the data pointer is just the this pointer, and the member function is wrapped in a static templated trampoline function i've called "member", to call the chosen member of the object:
void attach(void (*function)(void*), void *data);
template<class T, void (T::*member)(void)>
void member(void *object);
So e.g. to setup a callback to a member function of an object, it's now look like:
class Foo {
Foo() {
x.attach(member<Foo, &Foo::bar>, this);
}
void bar(); // desired callback function
AttachableObject x; // object with event
};
I think this is actually even a little simpler to use as it keeps the attach functions simpler too, and much better for implementation and reuse.
Please shout if you followed it this far and have an opinion either way!
Simon
Please ignore if the title didn't make sense; this is probably only interesting to a minority of people!
I've been doing some experiments tonight around pointers to member functions (among other things). The main problem is C++ really doesn't handle them at all well, and to get the functionality I wanted to allow people to register member functions as handlers in the current library, I really had to pull of some horrible tricks (even had to bring out memcpy in the trampoline :(.
However, I think i've finally hit on a better way based on reframing the problem slightly, and just want to give people a chance to shout if for some reason this new approach wouldn't work for them. I haven't worked through everything so there may be some hidden gotchas, but it is much simpler and gives basically the same functionality so I am very likely to make this change assuming there are no blockers.
Here is the explanation:
Currently, any class that accepts registration of static functions and member functions basically has something like the following:
Whilst the interface is ok(ish), the implementation for this has to jump through hoops. It basically comes from the problem that pointers to member functions are not guaranteed to be alike. It also means new code generated for every type of member function attached (it is a template), which carries through to classes that expose it further up the chain.
Ok, so what I propose is that the basic static attach can also provide a void* pointer to some data, that is provided back on callback. And as soon as it does that, everything gets much easier! (hindsight is a wonderful thing!). So now for member functions, the data pointer is just the this pointer, and the member function is wrapped in a static templated trampoline function i've called "member", to call the chosen member of the object:
So e.g. to setup a callback to a member function of an object, it's now look like:
I think this is actually even a little simpler to use as it keeps the attach functions simpler too, and much better for implementation and reuse.
Please shout if you followed it this far and have an opinion either way!
Simon