TemplateSpecialization

Template Specialization

Templates define the behavior of families of classes or functions. Often it is required that particular types or non-types may be treated special. To support this use case, you can specialize templates.

 TemplateSpecialization

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 particular 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 specialization don’t have to be identical to those of the primary template. The compiler prefers fully specialized to partially specialized templates and partially specialized templates to primary templates.

 

Rainer D 6 P2 500x500Modernes C++ Mentoring

Be part of my mentoring programs:

  • "Fundamentals for C++ Professionals" (open)
  • "Design Patterns and Architectural Patterns with C++" (open)
  • "C++20: Get the Details" (open)
  • "Concurrency with Modern C++" (starts March 2024)
  • Do you want to stay informed: Subscribe.

     

    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>{};
    

     

    • Primary Template

    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 unnecessary, a declaration such as in line 1 is acceptable.

    • Partial Specialization

    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.

    • Full Specialization

     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 mathematics, 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.

    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 parameters. Regarding 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) is a point in the 3-dimensional space. 

    What happens 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 entire specialization, m2 uses the partial specialization, and m3 uses the primary template, which causes an error because the definition is missing.

    To understand this process, you must remember a few rules. Here are the rules that apply, in particular, to the partial specialization of class templates.

    Dependencies between the Template Parameter and the Template Arguments

    • The number and sequence of the explicitly specified template arguments (<T, 3, 3>) must match the number and sequence of the template parameter list (<typename T, int Line, int Column>) of the primary template.
    • If you use defaults for template parameters, you don’t have to provide the template arguments. Only the primary template accepts defaults for template parameters.

    Valid Partial Specializations

    • The compiler chooses a partial specialization if the template instantiation arguments (Matrix<double, 3, 3>) are a subset of the template arguments of the partial specialization (Matrix<T, 3, 3>).

    Chosen Template Specialization

    1. The compiler finds only one specialization. The compiler uses this specialization.
    2. The compiler finds more than one specialization. The compiler uses the most specialized one. If this process ends in more than one specialization, the compiler throws an error.
    3. The compiler finds no specialization. It uses the primary 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:

    • Template B can accept all arguments that template A can accept.
    • Template B can accept arguments that template A cannot accept.

    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 with 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 is quite similar to ordinary classes or functions.

     

     

     

     

     

     

     

    Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, Marco Parri Empoli, moon, Philipp Lenk, Hobsbawm, and Charles-Jianye Chen.

    Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.

    My special thanks to Embarcadero
    My special thanks to PVS-Studio
    My special thanks to Tipi.build 
    My special thanks to Take Up Code
    My special thanks to SHAVEDYAKS

    Seminars

    I’m happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.

    Standard Seminars (English/German)

    Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.

    • C++ – The Core Language
    • C++ – The Standard Library
    • C++ – Compact
    • C++11 and C++14
    • Concurrency with Modern C++
    • Design Pattern and Architectural Pattern with C++
    • Embedded Programming with Modern C++
    • Generic Programming (Templates) with C++
    • Clean Code with Modern C++
    • C++20

    Online Seminars (German)

    Contact Me

    Modernes C++ Mentoring,

     

     

    0 replies

    Leave a Reply

    Want to join the discussion?
    Feel free to contribute!

    Leave a Reply

    Your email address will not be published. Required fields are marked *