Template Specialization
This post is a cross-post from www.ModernesCpp.com.
Templates define the behavior of families of classes or functions. Often it is required that special types or non-types may be treated special. To support this use case, you can specialize templates.
Let me start this post with the general idea of template specialization. In the next post, I concentrate on the details.
Template Specialization
Templates define the behavior of families of classes and functions. Often it is required that special types or non-types must be treated special. Therefore, you can fully specialize templates.
Class templates can also be partially specialized. The general or primary template can coexist with partially or fully specialized templates. The member functions and attributes of a specialization don’t have to be identical with those of the primary template. The compiler prefers fully specialized to partially specialized templates, and partially specialized templates to primary templates.
The following example should clarify my words.
template <typename T, int Line, int Column> // (1)
class Matrix;
template <typename T> // (2)
class Matrix<T, 3, 3>{};
template <> // (3)
class Matrix<int, 3, 3>{};
Line 1 is the primary or general template. The primary template has to be declared before the partially or fully specialized templates. If the primary template is not needed, a declaration such as in line 1 is fine.
Line 2 follows with the partial specialization. Only class templates support partial specialization. A partial specialization has template parameters and explicitly specified template arguments. In the concrete case, class Matrix<T, 3, 3> T is the template parameter and the numbers are the template arguments.
?Line 3 is the full specialization. Full means that all template arguments are specified and the template parameter list is empty: template <> in line 3.
Partial versus Full Specialization
To better understand partial and full specialization, I want to present a visual explanation. You may know, I studied mathematic and I had many linear systems of equations to solve.
Think about an n-dimensional space of template parameters. A partial specialization is a subspace in the n-dimensional space, and a full specialization is a point in the n-dimensional space.
Now, I apply my visual explanation to the class template Matrix and its partial and full specialization. In the primary template (line 1) you can choose a type as a template parameter, and two int values as non-type template parameter. In the case of the partial specialization in line 2, you can only choose the type. This means the 3-dimensional space is reduced to a line. The partial specialization of the primary template Matrix is, therefore, a subspace of the 3-dimensional space. The full specialization (line 3) stands for a point in the 3-dimensional space.?
What is happening when you invoke the templates?
Using the Primary, Partial, and Full Specialization
To remind you, the following specializations of the class Matrix are given.
template <typename T, int Line, int Column> // (1)
class Matrix;
template <typename T> // (2)
class Matrix<T, 3, 3>{};
template <> // (3)
class Matrix<int, 3, 3>{};
The question is: What happens when you instantiate Matrix for various template arguments? Here are three instantiations, and you see what the compiler creates.
Matrix<int, 3, 3> m1; // class Matrix<int, 3, 3>
Matrix<double, 3, 3> m2; // class Matrix<T, 3, 3>
Matrix<std::string, 4, 3> m3; // class Matrix<T, Line, Column> => ERROR
m1 uses the full specialization, m2 uses the partial specialization, and m3 the primary template which causes an error because the definition is missing.
To understand this process, you have to keep a few rules in mind. Here are the rules that apply, in particular, to the partial specialization of class templates.
Dependencies between the Template Parameter and the Template Arguments
Valid Partial Specializations
Chosen Template Specialization
领英推荐
Okay, there is one question left I have to answer. What does it mean that a template A is a more specialized template than another template B. This is my informal definition.
A template A is more specialized than a template B:
If you want to have it more formal, visit cppreference.com/partial_specialization and go to the subsection about partial ordering.
What's next?
This post should provide you the basics about template specialization but as always there are more details to it in C++. For example, partial or full specialization behaves like a compile-time if and full specialization of class or function templates are quite similar to ordinary classes or functions.
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, Marko, G Prvulovic, Reinhold Dr?ge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Animus24, Jozo Leko, John Breland, espkk, Louis St-Amour, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Neil Wang, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Tobi Heideman, Daniel Hufschl?ger, Red Trip, Alexander Schwarz, Tornike Porchxidze, Alessandro Pezzato, Evangelos Denaxas, Bob Perry, Satish Vangipuram, and Andi Ireland.
Thanks in particular to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, and Said Mert Turkal.
My special thanks to Embarcadero
?
Seminars
I'm happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
Bookable (Online)
German
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
New
Contact Me
Modernes C++
?
?
?
?
?
?
?