C++模板

来源:互联网 发布:罗尼库尔曼数据 编辑:程序博客网 时间:2024/06/03 21:04

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

下面是普通的函数调用

#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)因此而产生。增强了代码的灵活性。
模板的缺点:模板让代码变得凌乱复杂,不易维护,编译代码时间变长。搬移出错时,错误定位不准确。

0 0
原创粉丝点击