在某些情况下编译器不可能推演出模板实参的类型。如笔记(2)中所举的例子,如果模板实参推演过程为同一模板实参推演出两个不同的类型,则编译器会给出一个错误,指出模板推演失败。
在这种情况下,我们需要改变模板实参推演机制,使用显式指定(explicitly specify)模板实参。模板实参被显式指定在逗号分隔的列表中,用尖括号<>括起来,紧跟在函数模板实例的名字后面。如:
template <class T>
T min5( T, T ) {/* . . . */ }
// min5( unsigned int, unsigned int ) 被实例化
min5< unsigned int >( ui, 1024 );
在这种情况下,模板实参表< unsigned int >显式地指定了模板实参的类型。第2个实参是1024,其类型是int。因为第2个函数参数的类型通过显式模板实参已被固定为unsigned int,所以第2个函数实参通过有序标准转换被转换成类型unsigned int。
在显式特化中,我们只需列出不能被隐式推演的模板实参,如同缺省实参一样,我们只能省略尾部的实参。如:
template <class T1,class T2,class T3>
T1 sum ( T2, T3) ;
// OK: T3是unsigned int,T3从ui的类型中推演出来
ui_type loc3 = sum<ui_type,char>(ch,ui);
// OK: T2是char,T3是unsigned int,T2和T3从pf的类型中推演出来
ui_type (*pf)(char,ui_type) = &sum<ui_type>;
// ERROR: 只能省略尾部的实参
ui_type loc4 = sum<ui_type , , ui_type>(ch,ui);
必须要指出,显式模板实参应该只被用在完全需要它们来解决二义性,或在模板实参不能被推演出来的上下文中使用模板实例时。