I have some subscription function that will call my callback when something happens. (Let's say it's a timer, and will pass me an object when a certain number of milliseconds elapses.) The thing I want to be called is a virtual method. I feel std::function
and std::bind
or lambdas are part of the solution.
The C++99 approach I've used until now involves one-line C functions that know how to call a virtual method. The subscription function takes the C function and a void* user data as arguments. For example:
class Foo {
virtual void OnTimerA( Data* pd );
};
void OnTimerACB( Data* pd, void* pvUserData ) {
( (Foo*) pvUserData )->OnTimerA( pd );
}
/* Inside some method of Foo; 1000 is a number of milliseconds to call me back in;
second arg is a function pointer; third is a void* user data that is passed back
to the C callback. */
SubscribeToTimerOld( 1000, OnTimerACB, this );
What I'm hoping for is a way to write:
SubscribeToTimerNew( 1000, OnTimerA );
or something similar, at least that disposes of the need to write that one-line C binding callback.
I have a feeling that SubscribeToTimerNew()
's argument is probably a std:function
of some sort and instead of merely writing OnTimerA
I'd have to write something with std::bind
to get the this
pointer in there.
Alternatively to bind
, perhaps a lambda is the way to do it? This compiles, though I dont see how to extend it to let the event handler pass an argument to OnTimerA()
. (My linker isn't currently working so don't know if it links or runs as desired.)
SubscribeTimer( 1000, [this](){this->OnTimerA();} );
To mention one alternative I've discarded: give Foo
a superclass with a method called OnTimer()
that will be called when the timer goes off. Now SubscribeTimer()
only need take an elapsed time. I don't like this as it doesn't cleanly allow for multiple timers to be registered. If it did you could give them (say) integer timer ID's and implement OnTimer()
as a switch
but this seems to be a lot more complicated than the C++99 solution.
Ultimately of the (I assume) several approaches, are there any trade-offs (e.g., heap use) in addition the most obvious question of how much typing is involved? (This is a high-performance application and I'd prefer to minimize or eliminate heap usage.)