Boost logo

Boost Users :

From: Stefan Schild (schilds_at_[hidden])
Date: 2006-10-06 17:00:51


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:
        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;
}

.
.
.
Do I make any sense???


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net