How it works...

Class template type deduction is a much-needed feature in C++17 as it helps to reduce both the redundancy and verbosity of our C++. There are situations where, however, the compiler will deduce the wrong type—an issue that could be addressed if we didn't rely on type deduction. To better understand this type of issue, let's look at the following example:

template<typename T>
class the_answer
{

public:
the_answer(T t)
{
show_type(t);
}
};

In the preceding example, we have created a simple class template whose constructor takes a type T and uses a show_type() function to output whatever type it is given. Now suppose that we wish to use this class to instantiate a version that takes an unsigned integer. There are two ways to do this:

the_answer<unsigned> is(42);

The preceding method is the most obvious as we are explicitly telling the compiler what type we wish to have, while not using type deduction at all. Another method to get an unsigned integer would be to use the proper numeric literal syntax as follows:

the_answer is(42U);

In the preceding example, we are leveraging type deduction, but we have to make sure we always add U to our integers. The advantage of this approach is that the code is explicit. The disadvantage to this approach is that if we forget to add U to state that we wish to have an unsigned integer, we could inadvertently create a class with the int type instead of the unsigned type.

To prevent this issue, we can leverage a user-defined type deduction to tell the compiler that if it sees an integer type, we really mean an unsigned type, as follows:

the_answer(int) -> the_answer<unsigned>;

The preceding statement tells the compiler that if it sees a constructor with an int type, int should produce a class with the unsigned type.

The left-hand side takes a constructor signature, while the right-hand side takes a class template signature.

Using this method, we can take any constructor signature that we see and convert it into the class template type we wish, as in this example:

the_answer(const char *) -> the_answer<std::string>;

The user-defined type deduction guide tells the compiler that if it sees a C-style string, it should create std::string instead. We can then run our example with the following:

int main(void)
{
the_answer is("The answer is: 42");
}

We then get the following output:

As shown in the preceding screenshot, the class was constructed with std::string (or at least GCC's internal representation of std::string) and not a C-style string.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset