这里主要是对函数模板和普通函数的知识点进行比较补充,关于函数模板的基础知识在第一篇文章,链接如下:
C++提高编程,模板---函数模板_凌~风的博客-优快云博客
1.2.2普通函数和函数模板的区别:能否发生隐式类型转换?
1、普通函数是可以发生隐式类型转换的,
2、而函数模板的自动类型转换不可以,显示类型转换是可以的
这里再跟大家复习一下函数模板的自动类型转换和显示类型转换,所谓自动类型转换就是说编译器会自动识别输入的数据类型,不需要我们指出,而显示类型转换就是说需要我们给定,具体的我在下面的代码中体现:
#include <iostream>
using namespace std;
int myAdd01(int a,int b) //普通函数
{
return a+b;
}
template <class T> //函数模板
T myAdd02(T a, T b)
{
return a+b;
}
void test01()
{
int a=10;
int b=20;
char c='c'; //顺便复习ascii码,A是65,a是97,不要忘了!
cout<<"普通函数的:"<<endl;
cout<< myAdd01(a,b) <<endl;
cout<<myAdd01(a,c)<<endl; //此时会发生隐式类型转换,把c转换成int 型,为99
cout<<"函数模板的:"<<endl;
//自动类型转换
cout<<myAdd02(a,b)<<endl;
//cout<<myAdd02(a,c)<<endl; //此时就会报错无法执行,因为编译器不知到T到底是什么类型
//显示类型转换,指出所给的是int类型
cout<<myAdd02<int>(a,c)<<endl; //此时可以发生隐式类型转换,前提是函数形参不是引用形式,
//个人理解,因为如果传的是引用,相当于起别名,此时要将char型的c转int就不行
//而如果只是值传递,那么只是把‘c’的值先转换为int型,再进行相加,就是可以的
}
int main()
{
test01();
return 0;
}
1.2.3函数模板和普通函数的调用规则:
1、如果函数模板和普通函数都可以调用,优先调用普通函数
2、可以通过空模板参数列表来强制调用函数模板
3、函数模板也可以发生函数重载
4、在函数模板产生了更好的匹配的时候,优先调用函数模板
下面以代码为例具体讲解这几条规则:
#include <iostream>
using namespace std;
void myprint(int a,int b) //普通函数
{
cout<<"普通函数的调用"<<endl;
}
template <class T> //函数模板
void myprint(T a,T b)
{
cout<<"函数模板的调用"<<endl;
}
template <class T>
void myprint(T a,T b, T c) //函数名一样,参数个数不同,实现函数重载
{
cout<<"函数模板重载的调用"<<endl;
}
void test01()
{
int a=10;
int b=20;
//1、如果函数模板和普通函数都可以调用,优先调用普通函数
myprint(a,b);//此时两个函数都可以调用,编译器就会优先调用普通函数
//2、可以通过空模板参数列表来强制调用函数模板
myprint<>(a,b); //强制调用
//3、函数模板也可以发生函数重载
myprint(a,b,100); //编译器自然会调用重载函数
//4、在函数模板产生了更好的匹配的时候,优先调用函数模板
char c='c';
char d='d';
myprint(c,d); //此时普通函数和函数模板都可以调用,但是普通函数调用需要先强制类型转换,而函数模板则直接识别T的类型就可以调用,所以优先调用了函数模板
}
int main()
{
test01();
system("pause");
return 0;
}
这里提醒大家:既然提供了函数模板,最好就不要再提供普通函数,否则容易发生二义性!
1.2.4模板的局限性
1、模板的通用性并不是万能的,如果传入的是数组,或者自定义数据类型,就不行
2、利用具体化的模板,可以解决自定义数据类型
3、学习模板是为了学习使用STL做准备的
下面依旧是以代码为例具体讲解这几条规则:
#include <iostream>
using namespace std;
class person //定义一个person类
{
public:
string m_name;
int m_age;
person(string name, int age)
{
m_name=name;
m_age=age;
}
};
template <class T>
bool func(T &a, T &b)
{
if(a==b) //此时编译器不会比较两个自定义数据类型的大小
{
return true;
}
else return false;
}
//解决方法:利用具体的person的版本实现代码,具体化优先调用
template <> bool func(person &p1, person &p2) //代码应放在函数定义后,不然编译器不认识这个函数
{
if(p1.m_name==p2.m_name&&p1.m_age==p2.m_age)
{
return true;
}
else return false;
}
void test01()
{
person p1("张三", 18);
person p2("张三", 19);
bool ret=func(p1,p2);
if(ret)
{
cout<<"p1==p2"<<endl;
}
else cout<<"p1!=p2"<<endl;
}
int main()
{
test01();
return 0;
}
以上就是对函数模板知识的补充讲解,大家多多做题熟悉!