2012-04-05 19:56:22|?次阅读|上传:wustguangh【已有?条评论】发表评论
⑶ 模板函数类似于重载函数,但两者有很大区别:函数重载时,每个函数体内可以执行不同的业务逻辑,但同一个函数模板实例化后的模板函数都必须执行相同的业务逻辑。
函数模板中的模板形参可实例化为各种类型,但当实例化模板形参的各模板实参之间不完全一致时,就可能发生错误,如:
template<typename T> void min(T &x, T &y){ return (x<y)?x:y; } void func(int i, char j){ min(i, i); //正确调用 min(j, j); //正确调用 min(i, j); //错误调用 min(j, i); //错误调用 }
例子中的后两个调用是错误的,出现错误的原因是,在调用时,编译器按最先遇到的实参的类型隐含地生成一个模板函数,并用它对所有模板函数进行一致性检查,例如对语句:
min(i, j);
先遇到的实参i是整型的,编译器就将模板形参解释为整型,此后出现的模板实参j不能解释为整型而产生错误,此时没有隐含的类型转换功能。解决此种异常的方法有两种:
⑴采用强制类型转换,如将语句min(i, j);改写为min(i,int( j));
⑵用非模板函数重载函数模板
用非模板函数重载函数模板的方法有两种:
① 借用函数模板的函数体
此时只声明非模板函数的原型,它的函数体借用函数模板的函数体。如改写上面的例子如下:
template<typename 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(j, j);
min(i, j);
min(j, i);
}
执行该程序就不会出错了,因为重载函数支持数据间的隐式类型转换。
② 重新定义函数体
就像一般的重载函数一样,重新定义一个完整的非模板函数,它所带的参数可以随意。C++中,函数模板与同名的非模板函数重载时,遵循以下调用原则:
• 寻找一个参数完全匹配的函数,若找到就调用它。若参数完全匹配的函数多于一个,则这个调用是一个错误的调用。
• 寻找一个函数模板,若找到就将其实例化生成一个匹配的模板函数并调用它。
• 若上面两条都失败,则使用函数重载的方法,通过隐式类型转换产生参数匹配,若找到就调用它。
• 若上面三条都失败,还没有找都匹配的函数,则这个调用是一个错误的调用。
好了,C++函数模板的使用及注意事项便介绍完成了,欢迎大家共同讨论。