And here is the same thing using variadic template arguments, a new feature of C++11:
template
{
public:
virtual R operator()(Args... p) { return R(); }
};
template
{
T* _obj;
union
{
R (T::*_ptr)(Args...);
R (T::*_ptr_c)(Args...) const;
};
public:
stub_t(T* obj, R (T::*ptr)(Args...))
: _obj(obj), _ptr(ptr)
{
}
stub_t(T* obj, R (T::*ptr)(Args...) const)
: _obj(obj), _ptr_c(ptr)
{
}
R operator()(Args... p)
{
return (_obj->*_ptr)(p...);
}
};
template
{
R(*_ptr)(Args...);
base_t
public:
signal_t() : _ptr(nullptr), _stub(nullptr)
{
}
void connect(R(*ptr)(Args... args))
{
_ptr = ptr;
};
template
{
_stub = new stub_t
}
template
{
_stub = new stub_t
}
template
{
_stub = new stub_t
}
template
{
_stub = new stub_t
}
R operator()(Args... p)
{
if(_ptr)
return _ptr(p...);
else if(_stub)
return (*_stub)(p...);
else
return R();
}
};
Saves a few hundred lines of code, as well as reducing the number of places bugs can crop up.
