c++ strong types holy grail

Exact types of Fasteners
Exact types of Fasteners type. It is impossible to confuse them with each other.

This is the second installment of an aptly named “c++ strong duck” post. If you haven’t before please make a slight detour for a brief introduction on strong types.

I just thought to make a little post about the use-case scenarios of this seemingly “toy concept”, whatever that means.

For me the core benefits are simplicity and applicability to both C and C++. And , I indeed can show a few, perhaps surprisingly effective, examples.

I see nothing wrong with using macros in this instance. Here is the core single macro.  Please rename it if it clashes with something in your development environment.

That creates the strong type , a simple struct with the required type name and with the member v of the required value_type.

That is “almost C”. I am sure C aficionados, will be more than able to make a C version.  Let’s dive into some hopefully convincing use cases.

First classical use case: strong types as “units”. We want units to be distinctive types, not intrinsic (native) types, where only values are named appropriately. Here is how we generate few declaration of string types, representing various units.

That’s about it. Do not loose the fact, about the simplicity of the code generated above.  I have not seen simpler implementation of the strong types idea.

Now we can easily code rather safe and simple transformations of linear units, aka lengths. For example.

Note how these overloads will never confuse the compiler, and in turn, the compiler will never confuse you. The usage.

Non allowed transformations simply do not compile.

Nested types

Strong types are indeed useful as class members. In which case they are nested types.

That is indeed simple and it works as long as intrinsic types are used for value types of nested types.  Otherwise things will go very complex very quickly.

Note: in this post I am using C++20 “designated initializers“. They are already working in all three main compilers.

Now to reach the actual X and Y values one must type:

Not exactly simple or trivial.  So, please stick to single level nesting.

Above declaration is useful and allows for simple,elegant and safe code

The key point is one can not make a mistake of mixing x and y. They are  strong types, not intrinsic arithmetic types. That is the whole point of using strong types. One simply can not make a mistake.

Complex nested strong types

Often times , we have complex scenarios and we simply can not evade nesting complex strong types as class members. With a bit of thinking we can solve that issue too.

Let us assume we want to add some color to our Duffy, the strong  duck from the fist post on strong types.

Color is combination of red, green and blue components.  And them components are expressed as hex values. Let’s generate the required code for this  design.

With the method mix() above we have solved the complexity required by users actually wishing to use the Color instances. Here is the Duck type.

Using the above here is how we create duffy but with some color added.

It even looks simple and logical. Now let’s see the usability.

And to actually use the color we do

Which type is std::array<Hex,3>.

I certainly will use this in production code. I hope, you have seen some value of this simple concept for your projects too.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.