Jonathan Boccara's blog

An Implementation Helper For The Curiously Recurring Template Pattern

Published May 19, 2017 - 11 Comments

In this final episode of the series on the Curiously Recuring Template Pattern, let’s see an implementation that makes it easier to write CRTP classes.

In case you missed an episode in the series, here they are:

Getting rid of static_cast

Writing repeated static_casts in CRTP base classes quickly becomes cumbersome, as it does not add much meaning to the code:

It would be nice to factor out these static_casts. This can be achieved by forwarding the underlying type to a higher hierarchy level:

Plus it deals with the case where the underlying object is const, which we hadn’t mentioned yet.

This helper can be used the following way:

Note that the static_cast is gone and a this-> appeared. Without it the code would not compile. Indeed, the compiler is not sure where underlying is declared. Even if it is declared in the template class crtp, in theory nothing guarantees that this template class won’t be specialized and rewritten on a particular type, that would not expose an underlying method. For that reason, names in template base classes are ignored in C++.

Using this-> is a way to include them back in the scope of functions considered to resolve the call. There are other ways to do it, although they are arguably not as adapted to this situation. In any case, you can read all about this topic in Effective C++ Item 43.

Anyway, the above code relieves you from writing the static_casts, which become really cumbersome when they are several of them.

All this works if you class only add one functionality via CRTP, but it stops working if there are more.

Adding several functionalities with CRTP

For the sake of the example let’s split our CRTP classes into two: one that scales values and one that squares them:

And add these two functionalities to the Sensitivity class:

This looks ok at first glance but does not compile as soon as we call a method of either one of the base class!

The reason is that we have a diamond inheritance here:

I tried to solve this with virtual inheritance at first, but quickly gave this up because I didn’t find how to do it simply and without impacting the clients of the crtp class. If you have a suggestion, please, voice it!

Another approach is to steer away from the diamond inheritance (which sounds like a good idea), by having every functionality (scale, square) inherit from its own crtp class. And this can be achieved by… CRTP!

Indeed, we can add a template parameter to the crtp class, corresponding to the base class.

Note the addition of the crtpType template parameter. EDIT: as suggested by Daniel Houck in the comments section, the private-constructor-and-friend-with-derived technique should also be applied on this template template parameter here.

Note that the template parameter is not just a typename, but rather a template<typename> class. This simply means that the parameter is not just a type, bu rather a template itself, templated over a type whose name is omitted. For example crtpType can be Scale.

This parameter is here to differentiate types only, and is not used in the implementation of crtp (except for the technical check in the friend declaration). Such an unused template parameter is called a “phantom type” (or to be more accurate here we could call it a “phantom template”).

The class hierarchy now looks like the following:

and we’re good to go.

A CRTP on a CRTP. Templates are so much fun.

Related articles:

Share this post! Facebooktwittergoogle_pluslinkedin    Don't want to miss out ? Follow:   twitterlinkedinrss

Receive regular updates to make your code more expressive.