C++提高编程,模板---函数模板(2)

这里主要是对函数模板和普通函数的知识点进行比较补充,关于函数模板的基础知识在第一篇文章,链接如下:

C++提高编程,模板---函数模板_凌~风的博客-CSDN博客

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;
}

以上就是对函数模板知识的补充讲解,大家多多做题熟悉!

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值