Stefan Schild wrote:
Ian McCulloch wrote:
Stefan, can you give more details, i.e. a *real* example where you want it to fail to compile, but it does?
I can give you the original design I thought may be possible to improve. It's out of memory so don't hit me if it contains bugs.
We have a message factory class that stores and executes message functors. The "DoDispatch" and "Execute" methods needs a pointer to T, because we want to access members of the derived class in the message functor (we want do to something useful...).
template<class T> class MessageFunctor { public: void Execute( T* target ) = 0; }
template<class T> class MessageFactory { // Contains the logic to store, find and execute // message functors. Something like: public:
I guess there is something like
typedef std::map
virtual void Dispatch( T* d, const int key ) { MessageFunctorMap::iterator mf = m_message_map.find(key); if ( mf != m_message_functor_map.end() ) mf->Execute( d ); } private: MessageFunctorMap m_message_functor_map; }
If we want to add message dispatching to any class, we apply the CRTP and add a dispatch method that calls DoDispatch with the this pointer:
class ControlledClass : public MessageFactory<ControlledClass> { void DoDispatch( const int key ) { DoDispatch( this, key ); } }
Now, if we were SURE that the T in the MessageFactory class is equal to ControlledClass, i.e., equal to a derived class, couldn't we get our hands on the this pointer in the MessageFactory class already? We would not need the DispatchMessage method any more...
template<class T> class MessageFactory { // Contains the logic to store, find and execute // message functors. Something like: public: virtual void Dispatch( const int key ) { // Make sure that T is equal to ControlledClass, // i.e., that the CRTP was used, so we can use this MessageFunctorMap::iterator mf = m_message_map.find(key); if ( mf != m_message_functor_map.end() ) mf->Execute( this ); } private: MessageFunctorMap m_message_functor_map; }
In CRTP, the functions are usually not virtual. The ideom is
template<class T>
class MessageFactory
{
public:
typedef T self_type;
self_type& self() { return static_cast