[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A very useful extension to the functor concept is that of a Bound Callback.
Previously it was mentioned that closures were originally function calls
packaged up for later execution. Notice that in all of the Callback
descriptions above, there is no way to package up any parameters for use
later – when the Callback
is called via operator()
. All of
the parameters are provided by the calling function.
What if it is desired to allow the client function (the one that provides the
callback) to provide some of the parameters? Alexandrescu calls the process of
allowing a client to specify one of the parameters binding. One of the
parameters of operator()
has been bound (fixed) by the client.
Some of our pcap tracing code provides a nice example of this. There is a function that needs to be called whenever a packet is received. This function calls an object that actually writes the packet to disk in the pcap file format. The signature of one of these functions will be,
static void SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
The static keyword means this is a static function which does not need a
this
pointer, so it will be using C-style callbacks. We don’t want the
calling code to have to know about anything but the Packet. What we want there
is just a call that looks like,
m_promiscSnifferTrace (m_currentPkt);
What we want to do is to bind the Ptr<PcapWriter> writer
to the
specific callback implementation when it is created and arrange for the
operator()
of the Callback to provide that parameter for free.
We provide the MakeBoundCallback
template function for that purpose. It
takes the same parameters as the MakeCallback
template function but also
takes the parameters to be bound. In the case of the example above,
MakeBoundCallback (&CsmaHelper::SniffEvent, pcap));
will create a specific callback implementation that knows to add in the extra bound arguments. Conceptually, it extends the specific functor described above with one or more bound arguments
template <typename T, typename ARG, typename BOUND_ARG> class SpecificFunctor : public Functor { public: SpecificFunctor(T* p, int (T::*_pmi)(ARG arg), BOUND_ARG boundArg) { m_p = p; m_pmi = pmi; m_boundArg = boundArg; } virtual int operator() (ARG arg) { (*m_p.*m_pmi)(m_boundArg, arg); } private: void (T::*m_pmi)(ARG arg); T* m_p; BOUND_ARG m_boundArg; };
You can see that when the specific functor is created, the bound argument is saved
in the functor / callback object itself. When the operator()
is invoked with
the single parameter, as in
m_promiscSnifferTrace (m_currentPkt);
the implementation of operator()
adds the bound parameter into the actual
function call:
(*m_p.*m_pmi)(m_boundArg, arg);
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated on April 21, 2010 using texi2html 1.82.