函数模板可以被重载。如:
template < typename T >
class Array
{
//...
};
template < typename T >
T min( const Array<T>&, int );
template < typename T >
T min( const T*, int );
template < typename T >
T min( T, T );
int main()
{
Array< int > iA(1024);
int ia(1024);
//T==int; min( const Array<int>&, int )
int ival0 = min( iA, 1024 );
//T==int; min( const int*, int )
int ival1 = min( ia, 1024 );
//T==double; min( double, double )
double dval = min( sqrt(iA[0]), sqrt(iA[0]) );
}
成功地声明一组重载函数模板并不能保证它们可以被成功地调用。在调用一个模板实例时,重载的函数模板可能会导致二义性。如:
template < typename T >
int min( T, T )
{
//...
}
有以下调用:
int i;
unsigned int ui;
//OK;为T推出:int
min( 1024, i );
//模板实参推演失败
//为T推演出两个不同的类型
min( i, ui );
为了第二个调用,可以重载min(),允许两个不同的实参类型:
template < typename T, typename U >
int min( T, U )
{
//...
}
但不幸的是,原先的调用现在已变成二义的了:
//错误:二义性,来自min( T, T )和min( T, U )的两个可能的实例
min( 1024, i );
min()的第二个模板声明允许两个不同类型的函数实参,但是,它没有要求它们一定是不同的。在这种情况下,T和U都可以是int型。对于两个实参类型相同的调用,这两个模板声明都可以被实例。在这种情况下,我们其实可以取消重载函数模板。因为min(T,U)处理的调用集是由min(T,T)处理的超集,所以应该只提供min(T,U)的声明,而min(T,T)应该被删除。