I would like to implement a class "MyClass" that acts as a base for Observerable classes. For example:
class Observed : public MyClass<Observed>{
public: void DoWork() {.... MyClass<Observed>::NotifyObservers();}
};
class AnyObserver {public: HandleObserved(Observed& ob){...}};
AnyObserver any;
Observed observed;
observed.AddObserver(&any, &AnyObserver::HandleObserved);
observed.DoWork();.....
The following is the implementation I have so far. I believe this will work just fine, except I went into compilation problems.
template <typename T>
class MyClass
{
typedef std::tr1::function<void( T& )> CallbackFunction;
std::list< CallbackFunction > m_observers;
template<class S>
struct TypeHelper
{
//I. Compilation error is here: Unexpected "...
typedef void (typename S::*Signature)(T&);
};
public:
template<class M>
void AddObserver(M& observer, TypeHelper<M>::Signature callback)
{
CallbackFunction bound = std::tr1::bind(callback, observer, tr1::placeholders::_1);
m_observers.push_back(bound);
}
protected:
void NotifyObservers()
{
std::list< CallbackFunction >::iterator iter = m_observers.begin();
for (; iter != m_observers.end(); ++iter )
{
// II. is static_cast the right way to go?
(*iter)(static_cast<T&>(*this));
}
}
};
Any help with issues I and II (in comments) will be appreciated.
I: I define struct TypeHelper in an attempt to obtain the desired member pointer type. Couldn't figure out another way to do this when the class type it the templated M.
II: How can I enforce the template type in MyClass to match the type inheriting as in class Observed : public MyClass<Observed>
. What's the best approach here?