How it works...

Each time the compiler sees the use of a template class with a given type, it creates a version of that type implicitly. This, however, can happen multiple times, reducing the speed of the compiler. If, however, the types that are expected to be used are known upfront, this issue can be solved using explicit template specialization. Take a look at this example:

#include <iostream>

template<typename T>
class the_answer
{
public:
the_answer(T t)
{
std::cout << "The answer is: " << t << ' ';
}
};

Earlier, we created a simple structure that outputs to stdout during construction. Normally, this class would be created by the compiler once the first specialization of the class is seen. We can, however, perform the following:

template class the_answer<int>;
template class the_answer<unsigned>;
template class the_answer<double>;

This is similar to a class prototype, and it explicitly creates the specializations that we expect to use. These must be stated before they are used in code (which means they are usually stated after the definition of the template); however, once they are stated, they can be used as follows:

int main(void)
{
the_answer{42};
the_answer{42U};
the_answer{42.1};

return 0;
}

The output for the code is as follows:

As shown in the preceding example, we can create instances of our template as normal, but, in this case, we can speed up the compiler in scenarios where this class is used a lot. This is because, in the source code, we do not need to include the implementation of the template. To demonstrate this, let's look at another, more complicated example. In a header file (called recipe07.h), we will create our template using the following:

template<typename T>
struct the_answer
{
T m_answer;

the_answer(T t);
void print();
};

As you can see, we have a template class with no implementation for the provided functions. We will then provide the implementation of this template using the following in its own source file:

#include <iostream>
#include "recipe07.h"

template<typename T>
the_answer<T>::the_answer(T t) :
m_answer{t}
{ }

template<typename T>
void the_answer<T>::print()
{
std::cout << "The answer is: " << m_answer << ' ';
}

template class the_answer<int>;

As you can see in the preceding example, we added an explicit template declaration. This ensures that we generate the implementations for the class that we expect. The compiler will create the instances for the class that we expect explicitly, just like any other source that we would normally write. The difference is, we can explicitly define this class for whatever types we want. Finally, we will call this code as follows:

#include "recipe07.h"

int main(void)
{
the_answer is{42};
is.print();

return 0;
}

The output is as follows:

As you can see, we can call our class the same way we would if the class were defined with explicit types instead of a template class using a normal header file that is small and doesn't have the full implementation, allowing the compiler to speed up.

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

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