Traits in C++ is a concept of using templates in order to implement different behaviour for the same class/function depending on the types that are used inside of them.

Ok, so why am I writing about this again?

There are many readings about traits, but for some reason I had trouble with understanding them, probably because of lack of life examples. I finaly got it when I had to use them on my own. So I decided to tell about my work, so maybe it will help someone to understand what it is and what cool stuff can be done with it.

Goal

The goal of this example is to implement a simple container for one value. We want to keep it elastic, so we use templates:

Quickly we can notice, that this solution will make troubles with dynamically allocated objects:

The solution would be to delete allocated object in the destructor, but we can do this only for pointer types. How to detect them? This is where traits comes with help.

Deciding which method to use

Let’s look at this class:

The purpose of this class is to give us a return type every time when the Predicate parameter is set to true. In other words code:

will be translated into:

Why do we need this? We need this, because now we can create conditions, which tells the compiler which functions we can use for different variable types.

Let’s create a function, that will have different body for pointers and non-pointers. First of all we need conditions (traits):

And now the functions:

See what we did there? The compiler will generate DestroyItem functions for all used by us types, but it will generate different functions for pointer and non-pointer types!

Now the last thing is to use these methods in the destructor of our container:

What next?

We can of course create trait functions that returns the value:

Traits allows us to do more complex conditions. For example – what if we, for some reasons, don’t want to delete pointers to ints?

For more clarity we can create one big struct for traits!

As you can see traits can be nested:

Except of functions and specific types there are many other traits that can help us with types detection:

You can also, if there is a need for this, simply check the type inside the if condition:

C++11

The C++11 has many traits predefined inside the standard library, also the enable_if class template, so if you use it there is no need for defining many of traits by yourself. In C++11 our methods will look like this:

For other traits in C++11 check this page.

Summary

The power of traits and templates in general is that the code is generated during the compilation process, not during the runtime, which makes the final code run super fast. It also compansate the rather poor RTTI of C++. I hope the whole article clearen up you the concept of traits. Happy coding!