|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionTemplate 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 ProgrammingEvent-driven code is useful when writing a library and we want the library to provide default behavior in response to certain events, but to allow library users to provide custom behavior 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. The CodeHere 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; } ExplanationThis code represents how an event-driven library could be created. The basic The first The Notice that there is no explicit specialization Why is EventDispatch inside of a template?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.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||