Class templates allow class members to use template parameters as types. They are created
in the same way as function templates, but unlike functions templates a class template
must always be instantiated with the template parameter explicitly specified. Another thing
to remember when using class templates is that if we define a method outside of the
class template we must then also precede that definition with the template declaration.
Note that the template parameter between the angle brackets after the class name specifies
that the function's template parameter is the same as the class’s template parameter.
In addition to type parameters, templates can also have regular function-like parameters.
As an example, we can add an integer parameter that is used to decide the size of an array.
When we now instantiate this class template we have to include both a type and an integer.
Similar to function arguments template parameters can also be given default values and types.
To use these defaults we just need to leave the angle brackets empty when instantiating
the class template.
If we want to define a different implementation for a template, when a specific type is passed
as the template parameter, we can declare a template specialization. For example, in
this class template there is a print method that outputs the variable A. Say that when
the template parameter is a bool we would like it to print out “true” or “false”
instead of 1 or 0. One way to do this would be to create a class template specialization.
We then create a reimplementation of the class template where the template parameter list
empty. Instead we place a specialization parameter after the class template’s name
and we use this data type instead of the template parameter throughout the implementation. When
we now instantiate this class template with a boolean template type this template specialization
will be used instead of the standard one.
Note that there is no inheritance of members from the generic template to the specialized
template. We have to redefine the whole class. In this case, since there is only one function
that is different between the templates, a better alternative would instead be to create
a function template specialization. This way we only need to redefine the print method
and not the whole class.