C++模板

模板是泛型编程的一种,所谓泛型编程就是编写与类型无关的逻辑代码,是一种复用方式,模板分为模板类和模板函数

下面是普通的函数调用

#include<iostream>
using namespace std;
bool IsEqual(int left, int right)
{
    return left == right;
}
bool IsEqual(const string& left, const string& right)
{
    return left == right;
}
void test1()
{
    string s1("s1");
    string s2("s2");
    cout << IsEqual(s1, s2) << endl;
    cout << IsEqual(1, 1) << endl;
}
int main() 
{
    test1();
    system("pause");
    return 0;
}

可以发现上面的代码虽然可以正确的运行,但是有缺点,比如当需要比较其它类型的数据时,就需要再写对应类型的函数。这样不仅浪费时间,还是代码变得更加冗余,调试不方便。C++中解决这个问题,可以采用模板。
函数模板的格式:
template

template<typename T>
bool IsEqual(const T& left, const T& right)
{
    return left == right;
}
void test()
{
    string s1("s1");
    string s2("s2");
    cout << IsEqual(s1, s2) << endl;
    cout << IsEqual(1, 1) << endl;
}

int main() 
{
    test();
    system("pause");
    return 0;
}

这里写图片描述

这里写图片描述

IsEqual函数得到括号中的类型,然后进行推演,实例化出对应的类型函数

下面是程序执行时的反汇编代码,进一步验证了上图中模板函数的实例化

cout << IsEqual(s1, s2) << endl;
001B8790  rcl         byte ptr [edx-75h],1  
001B8793  or          eax,1C0090h  
001B8798  call        dword ptr ds:[1C009Ch]  
001B879E  cmp         edi,esp  
001B87A0  call        __RTC_CheckEsp (01B130Ch)  
001B87A5  mov         ecx,eax  
001B87A7  call        dword ptr ds:[1C00A0h]  
001B87AD  cmp         esi,esp  
001B87AF  call        __RTC_CheckEsp (01B130Ch)  
    cout << IsEqual(1, 1) << endl;
001B87B4  mov         dword ptr [ebp-12Ch],1  
001B87BE  mov         dword ptr [ebp-120h],1  
001B87C8  mov         esi,esp  
001B87CA  push        1B1497h  
001B87CF  lea         eax,[ebp-12Ch]  
001B87D5  push        eax  
001B87D6  lea         ecx,[ebp-120h]  
001B87DC  push        ecx  
001B87DD  call        IsEqual<int> (01B1488h)  
001B87E2  add         esp,8  
001B87E5  mov         edi,esp  
001B87E7  movzx       edx,al  
001B87EA  push        edx  
001B87EB  mov         ecx,dword ptr ds:[1C0090h]  
001B87F1  call        dword ptr ds:[1C009Ch]  
001B87F7  cmp         edi,esp  
001B87F9  call        __RTC_CheckEsp (01B130Ch)  
001B87FE  mov         ecx,eax  
001B8800  call        dword ptr ds:[1C00A0h]  
001B8806  cmp         esi,esp  
001B8808  call        __RTC_CheckEsp (01B130Ch)  

模板函数也可以看作重载函数,但是是有条件的,比如如果像上面的图一样将IsEqual函数屏蔽掉,那么模板函数不是重载函数,因为它没有实例化,只有实例化后,它才能视为重载函数,理由上面的图中已经说明了。
模板参数匹配及显示实例化

void test1()
{
    cout << IsEqual(1, 1) << endl;//结果为1
    //cout << IsEqual(1, 1.2) << endl;//模板参数不匹配,编译不通过
    cout << IsEqual<int>(1, 1.2) << endl;//将两个参数全部实例化成int类型,结果为1
    cout << IsEqual<double>(1, 1.2) << endl;//将两个参数全部实例化成double类型,结果为0
}

这里写图片描述

需要说明的是如果已经存在与某种类型有关的IsEqual函数,那么将直接调用这个IsEqual函数,不在进行实例化。//cout << IsEqual(1, 1.2) << endl;//这样调用编译会不通过,因为模板参数不匹配,编译器不知道到底要实例化成int类型还是double类型。cout << IsEqual(1, 1.2) << endl;这样调用是合法的,编译器不再进行推演,而是直接将两个参数全部实例化成int类型。
以上均是模板函数,关于类模板可以参考http://blog.csdn.net/nou_camp/article/details/69822642
http://blog.csdn.net/nou_camp/article/details/69844255

模板的优点:复用了代码, 节省了资源更快的迭代开发。C++的标准模板库(STL)因此而产生。增强了代码的灵活性。
模板的缺点:模板让代码变得凌乱复杂,不易维护,编译代码时间变长。搬移出错时,错误定位不准确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值