函数模板(泛型编程)

什么是函数模板

实际上是一种通用函数,其函数类型和参数类型不具体指定,用一个虚拟的类型来表示。这样的通用函数就是函数模板。

凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需要在模板中定义一次即可。在调用函数时系统会根据调用的实参类型来取代模板中的虚拟类型,从而实现不同函数的功能。

本质:类型参数化

为什么要有函数模板 

当开发中当存在功能相同,不需要重复修改业务逻辑时,函数模板可以减少相同代码的重复编写,提高效率。例如:写n个函数,交换char类型、int类型、double类型变量的值。

函数模板声明

template <类型形式参数表>

类型 函数名 (形参列表) { }

#pragma warning(disable : 4996)
#include <iostream>
using namespace std;

template <typename T>
void Swap(T &a,T &b)
{
    T temp = a;
    a = b;
    b = temp;
}

int main()
{
    int a = 10;
    int b = 20;
    Swap<int>(a, b);
    Swap(a, b);
    cout << "a = " << a << "b = " << b << endl;
    system("pause");
    return 0;
}

函数模板的调用:

Swap<int>(a, b);    //显示类型调用
Swap(a, b);            //自动数据类型推导

  • 函数模板定义由模板说明和函数定义说明
  • 模板说明的类属参数必须在函数定义中至少出现一次
  • 函数参数中可以使用类属类型参数,也可以使用一般类型参数
  • 模板类中如果有构造函数,和一般类的构造函数调用规则一样

类属——模板把函数或类要处理的数据类型参数化,表现为参数的多态性,称为类属。

#include <iostream>
using namespace std;

//相同参数类型
template <typename T>
///交换位置
void MySwap(T &a,T &b)
{
    T c = NULL;
    c = a;
    a = b;
    b = c;
}

//不同参数类型
template <typename T,typename T1>
///排序
void MySort(T *array,T1 size)
{
    T1 i, j;
    T temp = 0;
    for (i = 0; i < size;i++)
    {
        for (j = i+1; j<size;j++)
        {
            if (array[i] < array[j])
            {
                temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}

//不同参数类型
template <typename T,typename T1>
void MyPrint(T *array,T1 size)
{
    for (int i = 0; i < size; i++)
    {
        cout << array[i] << " ";
    }
}

int main()
{
    int a = 10;
    int b = 20;

    MySwap<int>(a, b);// 显示类型调用
    MySwap(a, b);//自动类型数据推导
    printf("a:%d,b:%d \n", a, b);

    char c = 'c';
    char d = 'd';

    MySwap<char>(c, d);//显示类型调用
    MySwap(c, d);//自动类型数据推导
    printf("c:%c,d:%c \n", c, d);

    int array[] = { 5,34,23,76,23,4,5,0,9,12,2,33 };
    int size = sizeof(array) / sizeof(*array);
    MySort<int,int>(array, size);// 显示类型调用
    MyPrint(array, size);//自动类型数据推导

    cout << endl;

    char cArray[] = "ashjku3256yiuuh";
    int len = strlen(cArray);

    MySort(cArray, len);
    MyPrint(cArray, len);

    system("pause");
    return 0;
}

函数模板和函数重载

  • 函数模板可以像普通函数一样被重载
  • C++编译器优先考虑普通函数
  • 如果函数模板可以产生一个更好的匹配,那么选择模板
  • 可以通过空模板实参列表的语法限定编译器只通过模板匹配
#pragma warning(disable : 4996)
#include <iostream>
using namespace std;
 
int Max(int a, int b)
{
    cout << "普通函数" << endl;
    return a < b ? b : a;
}
 
template <typename T>
T Max(T a, T b)
{
    cout << "模板函数" << endl;
    return a < b ? b : a;
}
 
template <typename T>
T Max(T a, T b, T c)
{
    cout << "模板函数" << endl;
    return Max(Max(a, b), c);
}
 
int main()
{
    int a = 10;
    int b = 20;
    char c = 'w';
 
    //当函数模板和普通函数都符合调用时,优先调用普通函数
    cout << Max(a, b) << endl;
 
    //如显示使用函数模板,则使用<>类型列表
    cout << Max<>(a, b) << endl;
    //如果函数模板产生更好的匹配 使用函数模板
    cout << Max(2.0, 5.0) << endl;
    //重载
    cout << Max(1.0, 3.0, 4.0) << endl;
    //调用普通函数 隐式类型转换
    cout << Max(a, c) << endl;
    system("pause");
    return 0;
}
template <typename T>
void myswap(T &a, T &b)

void myswap(char &a, int &b)

函数模板和普通函数区别:

函数模板不提供隐式的数据类型转换  必须是严格的匹配

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

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值