函数模板与模板函数
- 函数模板是一组函数的抽象描述,它不是一个实实在在的函数,函数模板不会编译成任何目标代码。函数模板必须先实例化成模板函数,这些模板函数再程序运行时会进行编译和链接,然后产生相应的目标代码。
函数模板的异常处理
- 函数模板中的模板形参可实例化为各种类型,但当实例化模板形参的各模板实参之间不完全相同,就可能发生错误,如:
template < class T>
void min(T& x,T& y) //函数模板
{
return (x<y)?x:y;
}
void func(int i,char j)
{
min(i,i); //实例化的模板函数,正确调用
min(i,j); //实例化的模板函数,但错误调用
}
-
上述代码中,min(i,i)的调用是正确的,而min(i,j)的调用是错误的。因为在函数模板中声明了min的两个参数必须是同一个类型,在调用时,编译器会对所有模板函数进行一致性检查。例如min(i,j)在编译时,编译器先将模板形参T解释为int类型,此后出现的模板形参j却为字符型,所以编译产生错误,此时没有隐含的类型转换功能。
-
解决此种异常的方法有两种:
1.采用强制类型转换,将min(i,j)改写为min(i,(int)j)。
2.用非模板函数重载函数模板,方法有两种:
①.借用函数模板的函数体。此时只声明非模板函数的原型,它的函数体借用函数模板的函数体,如:
template < class T>
void min(T& x,T& y) //函数模板
{
return (x<y)?x:y;
}
int min(int,int); //非模板函数重载函数模板解决异常问题
void func(int i,char j)
{
min(i,i);
min(i,j);
}
//这时执行不会出错,因为重载函数支持数据间的隐式类型转换。
②.重新定义一个完整的非模板函数。