Hello, my name is Jonathan Boccara. I'm your host on Fluent C++. I have been a C++ developer for 6 years, working for Murex which is a major software editor in the finance industry. My focus is on C++ and particularly how to write expressive code. I'm happy to take your feedback, don't hesitate to drop a comment on a post, follow me or get in touch directly !
Jonathan Boccara's blog
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.
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 combines an existing type with a metaclass in order to produce a new type that:
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:
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?
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.
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.