23-【其实学C最怕的就是拖着,越演到中场戏越肝不动了】函数模板

/*泛型编程*/

/*  模板概念


模板不可用直接使用,它只是框架,并不是万能的
【函数模板&类模板】
函数声明或定义 语法: template<typname T>

*/

#include<iostream>
#include<string>
using namespace std;


/*函数模板学习*/
void swap_01(int &a,int &b) // 交换整数
{
     int tmp = a;
     a = b;
     b = tmp;
}
void swap_02(double &a,double &b) // 交换浮点型
{
     double tmp = a;
     a = b;
     b = tmp;
}
template<typename T> //声明一个模板,告诉编译器后面的代码中的T,T是通用数据类型
void mySwap(T &a,T &b)
{
     T tmp = a;
     a = b;
     b = tmp;
}
void test_01()
{
    int a = 10;
    int b = 20;

    //调用方式
    mySwap(a,b);     //1-自动类型推导
    mySwap<int>(a,b);//2-显示指定类型
    cout << a <<" " <<b << endl;
}







/*函数模板注意事项:
1-自动类型推导  ,必须推导出一致的数据类型T才可以使用  mySwap(int,char)
2-模板必须要确定出T的数据类型,才可以使用
3-template<class T>也行
*/
template<typename T>
void show()
{
    cout << "lalala" << endl;
}
void test_02()
{
    //错 show();
    show<int>();
}






/*函数模板案例*/
//封装排序函数
// 规则 从大到小
// 算法 选择排序
// 测试 char int
template<class T>
void mySort(T arr[],int len)
{
    for(int i = 0;i < len ;i++)
    {
        int max = i;//认定最大值下标
        for(int j = i+1 ;j<len;j++) //遍历后面的值,谁大谁交换
        {
            //如果我们认定的最大值不如j,那么最大值就是j
            if(arr[max] < arr[j])
            {
                max =j; //更新最大值下标
            }
        }
        if(max!=i)
        {
            //交换元素
            mySwap(arr[i],arr[max]);
        }
    }
}

template<class T>
void printArray(T arr[],int len)
{
    for (int i = 0;i < len;i++)
    {
        cout << arr[i] <<" ";
    }
    cout << endl;
}
void test_03()
{
    //测试数组
    char charArr[] = "bdsacw";

    int num = sizeof(charArr)/sizeof(char);
    mySort(charArr,num);
    printArray(charArr,num);

}

void test_04()
{
    //测试数组
    int numb[] ={3,2,5,1,7,4,6,8};

    int num = sizeof(numb)/sizeof(int);
    mySort(numb,num);
    printArray(numb,num);

}




/*普通函数和函数模板区别
普通函数调用时可以自动发生隐式类型转换
函数模板-自动类型推导不可
函数模板-显示指定类型可
*/
//普通函数
int myAdd(int a,int b)
{
    return a+b;
}
//函数模板
template<class T>
int myAdd02(T a,T b)
{
    return a+b;
}
void test_05()
{
    int a = 10;
    int b = 20;

    cout << "a+b = " << myAdd(a,b) << endl;
    char c = 'c';
    cout << "a+c = " << myAdd(a,c) << endl; //自动转成ASCII
    cout << "模板 a+b = " << myAdd02(a,b) << endl;
    // 错 cout << "模板 a+c = " << myAdd02(a,c) << endl; 自动推导不能进行隐式类型转换
    cout << "模板 a+c = " << myAdd02<int>(a,c) << endl; //显示指定类型

}








/*普通函数&函数模板调用*/
// 优先调用普通函数
// 强制调用函数模板
// 函数模板重载
// 函数模板更好的匹配时,优先使用函数模板
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 test_06()
{
    int a = 10;
    int b = 30;
    int c = 200;
    myPrint(a,b);  // 优先调用普通函数
    // 普通函数 只有声明没有实现 会报错
    myPrint<>(a,b);// 强制调用函数模板  通过模板参数列表
    myPrint(a,b,c);// 函数模板也可以发生重载
    char c1 = 'b';
    char c2 = 'a';
    myPrint(c1,c2);// 函数模板产生更好的匹配-优先函数模板
}






/*函数模板的局限性
模板不是万能的,特殊的类型需要特殊的实现

*/


class Person
{
public:
    Person(string name,int age)
    {
        this->m_name = name;
        this->m_age = age;
    }
    string m_name;
    int m_age;
};
template<class T>//对比两个数据是否相等
bool myCompare(T a,T b)
{
    if(a==b)
    {
        return true;
    }
    else
    {
        return false;
    }
}

//利用具体化的Person的版本,具体化优先调用
template<> bool myCompare(Person &p1,Person &p2)
{
    if(p1.m_name == p2.m_name && p1.m_age == p2.m_age)
    {
        return true;
    }
    else
    {
        return false;
    }

}
void test_07()
{
    int a = 10;
    int b = 20;
    cout << myCompare(a,b) << endl;
}
void test_08()
{
    Person p1("tom",23);
    Person p2("poly",22);
    //bool ret = myCompare(p1,p2);
    //cout << ret << endl;
}



int main()
{
    test_02();
    test_01();
    test_03();
    test_04();
    test_05();
    test_06();
    test_07();
    test_08();
    system("pause");
    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/magic_shuang/article/details/107591833