Below is the code for my templated callback implementation. Currently it works for a single parameter. One thing I was going to try and do next was increase the argument to the function from 1..N arguments. Ideally this would be as simple as adding Args... everywhere using variadic templates. I don't have a lot of experience yet with variadic templates so any advice on this is helpful.
#include <iostream>
#include <vector>
template <typename R, typename Arg>
class Callback
{
public:
typedef R (*FuncType)(void*, Arg);
Callback (FuncType f, void* subscription) : f_(f), subscription_(subscription) { }
R operator()(Arg a)
{
(*f_)(subscription_,a);
}
private:
FuncType f_;
void* subscription_;
};
template <typename R, typename Arg, typename T, R (T::*Func)(Arg)>
R CallbackWrapper (void* o, Arg a)
{
return (static_cast<T*>(o)->*Func)(a);
}
class Pricer
{
public:
typedef Callback<void,unsigned int> CbType;
void attach ( CbType cb )
{
callbacks_.emplace_back(cb);
}
void receivePrice ( double price )
{
broadcast(static_cast<unsigned int>(price*100));
}
void broadcast (unsigned int price)
{
for ( auto& i : callbacks_)
{
i(price);
}
}
private:
std::vector<CbType> callbacks_;
};
class Strategy
{
public:
Strategy(Pricer* p) : p_(p)
{
p->attach(Callback<void,unsigned int>(&CallbackWrapper<void,unsigned int, Strategy, &Strategy::update>, static_cast<void *>(this)));
}
void update(unsigned int price)
{
//update model with price
std::cout << "Received price: " << price / 100.0 << std::endl;
}
private:
Pricer* p_;
};
int main ( int argc, char *argv[])
{
Pricer p;
Strategy s(&p);
p.receivePrice(105.67);
}