将某些模板参数组合视为特殊的参数可以提高性能,如以下 twice 示例所示。而模板说明可能无法用于其一组可能的参数,如以下 sort 示例所示。模板专门化允许您定义实际模板参数给定组合的可选实现。模板专门化覆盖了缺省实例化。
使用模板参数的组合之前,您必须声明专门化。以下示例声明了twice 和 sort 的专用实现。
template <> unsigned twice<unsigned>( unsigned original ); |
template <> sort<char*>(Array<char*> store); |
如果编译器可以明确决定模板参数,则您可以省略模板参数。例如:
template <> unsigned twice(unsigned original); |
template <> sort(Array<char*> store); |
必须定义声明的所有模板专门化。下例定义了上一节中声明的函数。
template <> unsigned twice<unsigned>(unsigned original) {return original << 1;} |
#include <string.h> template <> void sort<char*>(Array<char*> store) {int num_elems = store.GetSize(); for (int i = 0; i < num_elems-1; i++) for (int j = i+1; j < num_elems; j++) if (strcmp(store[j-1], store[j]) > 0) {char *temp = store[j]; store[j] = store[j-1]; store[j-1] = temp;}} |
专门化与其他任何模板一样使用并实例化,除此以外,完全专用模板的定义也是实例化。
在前一个示例中,模板是完全专用的。也就是说,模板定义了特定模板参数的实现。模板也可以部分专用,这意味着只有某些模板参数被指定,或者一个或多个参数被限定到某种类型。生成的部分专门化仍然是模板。例如,以下代码样本说明了主模板和该模板的完全专门化。
template<class T, class U> class A {...}; //primary template template<> class A<int, double> {...}; //specialization |
以下代码说明了主模板部分专门化的示例。
template<class U> class A<int> {...}; // Example 1 template<class T, class U> class A<T*> {...}; // Example 2 template<class T> class A<T**, char> {...}; // Example 3 |
示例 1 提供了用于第一个模板参数是 int 类型的情况的特殊模板定义。
示例 2 提供了用于第一个模板参数是任何指针类型的情况的特殊模板定义。
示例 3 提供了用于第一个模板参数是任何类型的指针到指针而第二个模板参数是 char 类型的情况的特殊模板定义。