I think some of my confusion over what "Specialization" means is that it appears to have two related, though distinct meanings. These are the two definitions I've seem to come across:
From IBM Template Instantiation
The definition created from a template instantiation to handle a specific set of template arguments is called a specialization.
Which seems to mean, if I have some templated class:
template <typename T>
class Foo { ... };
That I create a specialization of Foo by simply instantiating Foo<int> for example.
This makes sense, as the template is merely a prototype, from which the compiler is creating a specialized definition specifically for int.
However, I have also seen template specialization referring to a different concept. Sometimes it seems to be called Full template specialization, while others it seems to be called partial template specialization. This seems to be the act of specifying separate "specialized" code for a subset of template arguments. So say I have this really contrived example where I want getMagnitude() to return some value for all types except for uint8_t, for which case I'd want to to first divide the value by 255. I could write this as:
template <typename T>
float getMagnitude(T value)
{
return static_cast<float>(value);
};
template <typename T>
float getMagniude<uint8_t>(T value)
{
return static_cast<float>(value)/255.f;
};
That way I still have a template for getMagnitude() but I can specialize it to behave differently for different template arguments. This also makes sense why it'd be called specialization, as it is specializing the behavior for certain template arguments.
Online and talking with other people though, it seems like this terminology isn't always clear (at least not to me). Is it the type of thing that should be clear from context alone? Or is there a way of differentiating between these two types of template specialization when speaking/writing documentation? (And further, are there possibly other types of template specialization I'm not aware of?)
The terminology is very clear and precise. Instantiation and specialization are different concepts, and can both be implicit or explicit.
[temp.spec]This is what your quote from the IBM documentation means. Instantiation (explicit or implicit) is one way to produce a specialization. The other way is explicit specialization. Note that an implicit specialization is not to be found in the code. Instead, it is produced at compile-time if necessary (required by an instantiation).
[temp.inst]Instantiation can be implicit (like when using
Foo<int>in your example), which is covered by the quote above, or explicit, which is covered by the quote below.[temp.explicit]For example:
Again, this is not an explicit specialization, so the compiler generates the specialization itself. You don't give it any implementation, it comes from the template.
An explicit specialization (
[temp.expl.spec]) is something you write in full. In your (invalid) example withgetMagnitude, it would look like this:Here,
getMagnitude<uint8_t>is an explicit specialization of the function templategetMagnitude. You provide the implementation.This is also known as explicit full template specialization, because all the template parameters are given a type or value. It is no longer a template.
The same can be done with classes. However, you can also partially specialize classes, unlike functions. This is known as class template partial specialization.
[temp.class.spec]Also important:
Example:
Note that the partial specialization is still a template: it requires at least one template parameter (
typename Vin this case, whereVcould also be replaced byT).