C++函数模板学习笔记

版权声明:经本人同意,方可转载。 https://blog.csdn.net/annjeff/article/details/81363141

1.引出问题


  • 我们需要一个函数来实现比较两个值得大小,要求可以比较int类型,char 类型等。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//对两个int类型数值比较大小
int compare(int num1, int num2)
{
    if (num1 > num2)
    {
        return 1;
    }
    else if (num1 < num2)
    {
        return -1;
    }
    return 0;
}
//对两个char类型变量比较大小
int compare(char ch1, char ch2)
{
    if (ch1 > ch2)
    {
        return 1;
    }
    else if (ch1 < ch2)
    {
        return -1;
    }
    return 0;
}
int main(void)
{
    int iNum1 = 14;
    int iNum2 = 23;
    cout<<compare(iNum1, iNum2)<<endl;
    char ch1 = 'f';
    char ch2 = 'c';
    cout << compare(ch1, ch2) << end;;
    system("pause");
    return 0;
}

此时,我们会发现,如果需要对两个double,或两个float进行比较, 还是需要重新编写相关的比较函数。此类重载繁多,非常繁琐,容易出错。因此对此类:函数功能一致仅类型不同的函数,C++提供了模板机制。


2. 函数模板


2.1 什么是函数函数模板?

函数模板就是一个创建类或函数的蓝图或者说公式。一个函数模板就是一个公式,可用来生成针对特定类型的函数版本。[摘自C++ primer第5版 578页]

2.2 函数模板的格式

//template是关键字
//第一行是关键字
//typename可换为class
template<typename T>
//template<class T>
int compare(T t1, T t2)
{
    if (t1 > t2)
    {
        return 1;
    }
    else if (t1 < t2)
    {
        return -1;
    }
    return 0;
}

2.3 函数模板与普通函数的区别

函数模板不允许自动类型转化.

普通函数能够自动进行类型转换

例子

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

template<class T>
void mySwap(T t1, T t2)
{
    T t = t1;
    t1 = t2;
    t2 = t;
    cout << "mySwap(T,T)....." << endl;
}
void mySwap(int iNum, char ch)
{
    int temp = iNum;
    iNum = ch;
    ch = temp;
    cout << "mySwap(int,char)...." << endl;
}
int main(void)
{
    int iVar1 = 15;
    int iVar2 = 18;
    mySwap(iVar1, iVar2);//此处调用的是模板函数
    char ch1 = 'a';
    mySwap(iVar1, ch1);//此时调用的是mySwap(int,char)
    mySwap(ch1, iVar1);//此时调用的是mySwap(int,char)


    system("pause");
    return 0;
}

第1处调用mySwap函数,因为模板函数能产生更好的匹配,过调用了模板函数。

第2处调用mySwap函数,因为普通函数类型匹配最好,故调用了普通函数。

第3处调用mySwap函数,虽然普通函数,模板函数都不匹配,但是普通函数可以进行自动类型转换,故可以调用普通函数。

2.4 调用规则

例子

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
void mySwap(int a, int b)
{
    int temp = a;
    a = b;
    b = temp;
    cout << "mySwap(int,int)被调用...." << endl;
}
template<class T>
void mySwap(T a, T b)
{
    T temp = a;
    a = b;
    b = temp;
    cout << "mySwap(T,T)被调用...." << endl;
}
int main(void)
{
    int iNum1 = 10;
    int iNum2 = 17;
    double doub1 = 3.14;
    double doub2 = 6.28;

    mySwap(iNum1, iNum2);
    /*
     * 此处调用普通函数mySwap(int,int),
     * 因为:
     * 普通函数和函数模板都符合条件,
     * 这种情况下优先考虑普通函数。
     */

    mySwap<>(iNum1, iNum2);
    /*
     * 此处调用:模板函数mySwap(int,int)
     * 因为:
     * 告诉编译器,只使用函数模板。
     */

    mySwap(doub1, doub2);
    /*
     * 此处调用:模板函数mySwap(T,T)
     * 因为:
     * 函数模板能产生更好的匹配,因此使用函数模板。
     */

    mySwap(iNum1, doub1);
    /*
     * 此处调用:普通函数mySwap(int,int)
     * 因为:
     * 调用普通函数,普通函数可隐式转换。
     */
    system("pause");
    return 0;
}


函数模板和普通函数在一起调用规则:

1.函数模板可以向普通函数那样可以被重载

2.c++编译器优先考虑普通函数

3.如果函数模板可以产生一个更好的匹配,那么选择模板

4.可以通过空模板实参列表的语法限定编译器只能通过模板四配

猜你喜欢

转载自blog.csdn.net/annjeff/article/details/81363141