Message dispatching in C++ (Part 2 – No more switch)

Last time we got rid of the enum and I promised to also get rid of the switch.

The switch is easy, just some template fiddling to generate some code.

Let’s start with the code this time:

This is all the code we need to get rid of our switch.

I use Dispatcher.dispatch() to wrap DispatcherImpl.do_dispatch() because I want to get the type’s index from the stream and hide the extra type_id parameter and the extra Cons template parameter, it’s just there for hiding these things.

I’m going to write the explanation in pseudo-code, DispatcherImpl.do_dispatch() is roughly equivalent to:

So that’s not so complicated, we just go trough the type list and compare our type id to the current item, if we get a hit, we instantiate that item (remember, list items are types).

The DispatcherImpl specialization is the stop condition for when we reach the end of our type list.

Because this is done at compile time and instead of function recursion we have recursive template instantiations (notice that DispatcherImpl inherits itsself) we get code generated for us. And because those methods can be inlined, for our three message types we get something like this:

This gets further simplified to:

Not as efficient as a jump table but pretty damn close.

Now, what’s the deal with that Handler thing? Well, that’s our second part of the dispatch, it’s the part where we do stuff with the messages.

The handler is just a normal class:

And that’s all.

Let’s see the original example:

A couple of extra things that I’ve done to clean up the code are: type_id() method to get a type’s id without messing with the IndexOf template (a shortcut) and a MessageWrapper that writes the message’s type into the stream automatically.

The thing I like best about this approach is that there isn’t a single virtual method in sight.

Download the whole code: dispatch.tar.gz (compiled with GCC 4.5)