c++ Type confusion stopper

C++ is hard. But you are advancing.  Things are becoming clearer and clearer.

By now you feel confident enough to tackle head-on the c++ meta-programming, perhaps? Compile-time shenanigans and the rest?

(Wandbox is here)

One tool seems very powerful: std::is_same<T1, T2> . Using this, one can achieve compile-time “magic” based on equality of two types.  For example.

 

But. This never seems to work as expected. And the chief reason for this kind of problems? Consider this:

template< typename T> 
void function( T t_ ) {
 // what is the type of T in here?
}

Somehow,  T is almost never a type you expect it to be. And you have to admit, probably you have not read the fundamentals of standard C++ before starting this journey on “the path peppered with a glass”? :) To answer that simple question “what is the type of T”:

One needs to know what exactly type T can be. In standard C++.

And speaking of types we immediately bump into SFINAE. SFINAE is one thing almost every C++ beginner puts under the carpet as long as possible. Until it has to be understood and used.

The core to success in taming SFINAE is your complete understanding of the classification of types in standard C++. Here is a quick set of names divided into two base categories of C++ types:

  1. Compound types
    Array, function, object pointer, function pointer, member object pointer, member function pointer, reference, class, union, or enumeration, including any cv-qualified variants.
  2. Fundamental types
    Arithmetic type (integral type or a floating-point type), void, or nullptr_t. Where the integral types are:  bool, char, char16_t, char32_t, wchar_t, short, int, long, long long, or any implementation-defined extended integer types, including any signed, unsigned, and cv-qualified variants

Huh? Yes, “it is as simple as that”, I am afraid.

So you bravely dive into standard C++ types taxonomy, and you quickly develop the habit to use standard and useful <type_traits> to fight it out with the types. And it seems so simple and logical when looking into examples online. But not so when you try it.

To help myself out ( and for painless using of C++ std::  goodies), I have developed a few useful template aliases, for taming this uncertainty situation around the “What is the type of  T” question.

Here I will present a tool that will reduce ‘anything’ to the base type.   Please look into the classification above now. So.  A tool that will reduce any compound type to the base fundamental type. Its most canonical usage:

“Base type” is not a fundamental type. The base type is a type which is a base of a compound type.  To clarify this completely let me show you some hard testing first. Here we use several legal C++ compound types, invented for testing only.

All compile time. As you can see this really works. Whatever compound type you give, it will be reduced to its base type.

This tool will also work for double, triple, etc pointers. And here is the tool itself:

Your problem function from above will have to be changed to use that.

Feel free to copy-paste and use. Just please leave in the copyright statement.

Obligatory Gist is here. That works for C++14, 17 and 20.

 

Leave a Reply

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