Jonathan Boccara's blog

Metaclasses, the Ultimate Answer to Strong Typing in C++?

Published August 8, 2017 - 0 Comments

Metaclasses are a very popular C++ feature that Herb Sutter proposed for the language a couple of weeks ago. I think that metaclasses are a structural change to the language if they are accepted, and this is why you should get familiar with it.

The paper dedicates a small subsection on the subject of how metaclasses could help with creating strong types (also called strong typedefs). A strong type is a type used in place of another type to carry specific meaning through its name. While this is not the bulk of the metaclasses paper, this could finally give a much expected native way to declare strong types in C++.

It’s great that those two concepts can collaborate, since both metaclasses and strong types are designed to make code more expressive and more robust.

Let’s see how metaclasses can help with strong typing, and also what they cannot do, at least with the current state of the proposal as I type these words.

How metaclasses can do strong typing

If you’re not familiar with metaclasses, I’ve written a summary of the proposal for you. So from this point on, I’m going to assume that you have a basic understanding of metaclasses.

The metaclass feature that strong typing relies on is the .as method.

The .as method combines an existing type with a metaclass in order to produce a new type that:

  • has all the added features brought by the metaclass,
  • complies by all the constraints imposed by the metaclass (and doesn’t compile otherwise):

metaclass as strong type

Strong typing is a particular case of that feature: it uses .as with an empty metaclass. No added features, no constraints. Therefore, the only thing left is just a new type that is a copy of the initial one. If this metaclass is called new_type, this gives a lovely syntax for the using expression:

Metaclass as new type

And another nice thing is that T2 has the same methods as T, which is hard to achieve with a library based solution.

Pretty neat, right?

No typing of intermediate strength

So, are metaclasses the ultimate answer to strong typing in C++?

I think that for many cases they will be a great tool for the job. But there are features of strong typing that metaclasses can’t seem to achieve, at least as they are worded today. For example, select which methods to inherit from the original type.

We’ve seen how to specify functionalities to inherit from the original type, and why this could be useful. Take the example of the the chrono library that manipulates time durations. chrono has a type, seconds,  that is essentially a strong type over an int. But it doesn’t do everything an int does. For instance, seconds doesn’t have an operator* because, within the context of the chrono library, it doesn’t make sense to multiply seconds. But metaclasses take all or nothing.

Another thing that metaclasses don’t automatically achieve is plugging in external features, like hashing for example. While making a library-based strong type hashable only took one word, I suppose that making a metaclassed strong type hashable needs a manual implementation of std::hash. But maybe I’m just shortsighted here and we’ll find an way to do it when we get to play around with compilers implementing metaclasses.

Getting down to Earth

It’s a long way ahead before we get metaclasses in production code though. The proposal hasn’t been debated, accepted, and even less incuded in the C++ standard. But there is a likely chance that some day we can use it to do strong typing natively and make our code ever more expressive.

Until that day, we can use the library-based implementation of strong types.

Related articles:

  • A Summary of the Metaclasses Proposal for C++
  • Strong types for strong interfaces
Liked it ? Share this post ! Facebooktwittergoogle_plus    Don't want to miss out ? Follow:   twitterrss

Receive regular updates to make your code more expressive.