2.2 Partial Template Specialization
Partial template specialization allows you to specialize a class template for subsets of that template's possible instantiations set.
Let's first recap total explicit template specialization. If you have a class template Widget,
templateclass Widget { ... generic implementation ... };
then you can explicitly specialize the Widget class template as shown:
template <> class Widget{ ... specialized implementation ... };
ModalDialog and MyController are classes defined by your application.
After seeing the definition of Widget's specialization, the compiler uses the specialized implementation wherever you define an object of type Widget and uses the generic implementation if you use any other instantiation of Widget.
Sometimes, however, you might want to specialize Widget for any Window and MyController. Here is where partial template specialization comes into play.
// Partial specialization of Widget templateclass Widget { ... partially specialized implementation ... };
Typically, in a partial specialization of a class template, you specify only some of the template arguments and leave the other ones generic. When you instantiate the class template in your program, the compiler tries to find the best match. The matching algorithm is very intricate and accurate, allowing you to partially specialize in innovative ways. For instance, assume you have a class template Button that accepts one template parameter. Then, even if you specialized Widget for any Window and a specific MyController, you can further partially specialize Widgets for all Button instantiations and My Controller:
templateclass Widget
As you can see, the capabilities of partial template specialization are pretty amazing. When you instantiate a template, the compiler does a pattern matching of existing partial and total specializations to find the best candidate; this gives you enormous flexibility.
Unfortunately, partial template specialization does not apply to functions—be they member or nonmember—which somewhat reduces the flexibility and the granularity of what you can do.
- Although you can totally specialize member functions of a class template, you cannot partially specialize member functions.
- You cannot partially specialize namespace-level (nonmember) template functions. The closest thing to partial specialization for namespace-level template functions is overloading. For practical purposes, this means that you have fine-grained specialization abilities only for the function parameters—not for the return value or for internally used types. For example,
template
T Fun(U obj); // primary template template void Fun (U obj); // illegal partial // specialization template T Fun (Window obj); // legal (overloading)
This lack of granularity in partial specialization certainly makes life easier for compiler writers, but has bad effects for developers. Some of the tools presented later (such as Int2Type and Type2Type) specifically address this limitation of partial specialization.