Search code examples
c++templatesc++11partial-specialization

How to read the template partial specialization?


Suppose the following declaration:

template <typename T> struct MyTemplate;

The following definition of the partial specialization seems to use the same letter T to refer to different types.

template <typename T> struct MyTemplate<T*> {};

For example, let's take a concrete instantiation:

MyTemplate<int *> c;

Now, consider again the above definition of the partial specialization:

template <typename T> struct MyTemplate<T*> {};

In the first part of this line (i.e. template <typename T>), T is int *. In the second part of the line (i.e. MyTemplate<T*>), T is int!

So, how is the definition of the partial specialization read?


Solution

  • Read it like this:

    1. The primary template says "MyTemplate is a class template with one type parameter":

      template <typename> struct MyTemplate;
      
    2. The partial specialization says, "whenever there exists a type T"...

      template <typename T>
      

      ... such that a specialization of MyTemplate is requested for the type T *"...

      struct MyTemplate<T *>
      

      ... then use this alternative definition of the template.

    3. You could also define explicit specializations. For example, could say "whenever the specialization is requested for type X, use this alternative definition:

      template <> struct MyTemplate<X> { /* ... */ };
      

    Note that explicit specializations of class templates define types, wheras partial specializations define templates.

    To see it another way: A partial class template specialization deduces, or pattern-matches, the structure of the class template arguments:

    template <typename T> struct MyTemplate<T *>
    //       ^^^^^^^^^^^^                  ^^^^^
    //       This is a new template        Argument passed to the original class
    //                                     template parameter
    

    The parameter names of this new template are matched structurally against the argument of the original class template's parameters.

    Examples:

    • MyTemplate<void>: The type parameter of the class template is void, and the primary template is used for this specialization.

    • MyTemplate<int *>: The type parameter is int *. There exists a type T, namely T = int, such that the requested type parameter is T *, and so the definition of the partial specialization of the template is used for this specialization.

    • MyTemplate<X>: The parameter type is X, and an explicit specialization has been defined for that parameter type, which is therefore used.