Sponsored Link •
|
Summary
C++ template specializations provide an elegant mechanism for implementing event-driven frameworks. This is the technique that I am using for defining semantic actions in the YARD parser. This is a reprint of an article I just posted to CodeProject.com.
Advertisement
|
Template specializations provide a mechanism by which we can create an event-driven framework, instead of using function pointers.
Template specializations are alternative definitions of a template for specific parameter values. They are sometimes known as user-defined specializations. For more information I recommend reading The C++ Programming Language, 3rd Edition by Bjarne Stroustrup.
There are two advantages of this approach, first no function pointer registration step is needed like in typical event-driven frameworks, and secondly the compiler can do a far better job of optimizing the call.
Event-driven code is useful when writing a library and we want the library to provide default behaviour in response to certain events, but to allow library users to provide custom behaviour to one or more events. This occurs frequently in the implementation of GUI libraries. A message loop has to dispatch events to user-defined functions. This is typically done either through virtual-functions or through function-pointers. Using template specializations is an easy to use and efficient alternative.
Here is a sample program, which demonstrates the usage of template specializations for callbacks:
const int RED_PILL = 0; const int BLUE_PILL = 1; template<int T> struct EventHandler { static void Event() { }; }; template<typename Dummy_T = void> struct Dispatcher { static bool EventDispatch(char ch) { switch (ch) { case 'a': { EventHandler<RED_PILL>::Event(); return true; } case 'b': { EventHandler<BLUE_PILL>::Event(); return true; } default : { return false; } } } }; template<> struct EventHandler<BLUE_PILL> { static void Event() { puts("Welcome to the matrix!"); }; }; int main() { puts("press a for the red-pill, b for the blue-pill"); char ch = getchar(); Dispatcher<>::EventDispatch(ch); return 0; }
This code represents how an event-driven library could be created. The basic EventHandler
and Dispatcher
classes represent what would be found in the library. The specializations and the main()
function represent what would be defined by the user of the library,
The first EventHandler
class is a template which contains empty functions defintions. This is the class which is specialized. The other EventHandler
class is are the template specializations defined by the user of a library. The programmer simply needs to provide implementations of the Event()
function and can do whatever else they want inside of it.
The Dispatcher
class houses a Dispatch()
function which triggers the appropriate user-defined event. The template parameter is ignored, but is provided to make sure that the class is constructed by the compiler after the specializations are defined by the programmer.
Notice that there is no explicit specialization EventHandler<RED_PILL>
. The default handler is called in this case, which does nothing. The call should be entirely removed by the optimizer.
This is a drawback of the technique due to compilation order dependencies. Typically in an event-driven framework we will want to define the specializations in code after the code where the specialization is used. As soon as the compiler sees a usage of the template it is too late for us to define a specialization. What I do then is define the usage within a template. This allows me to put off compilation of the usage until after the definition of the specializations.
Have an opinion? Readers have already posted 12 comments about this weblog entry. Why not add yours?
If you'd like to be notified whenever Christopher Diggins adds a new entry to his weblog, subscribe to his RSS feed.
Christopher Diggins is a software developer and freelance writer. Christopher loves programming, but is eternally frustrated by the shortcomings of modern programming languages. As would any reasonable person in his shoes, he decided to quit his day job to write his own ( www.heron-language.com ). Christopher is the co-author of the C++ Cookbook from O'Reilly. Christopher can be reached through his home page at www.cdiggins.com. |
Sponsored Links
|