C++中函数模版语法及数组排序案例实现,模版的局限性(附C++代码)

在这里插入图片描述

💪 图像算法工程师,专业从事且热爱图像处理,图像处理专栏更新如下👇:
📝《图像去噪》
📝《超分辨率重建》
📝《语义分割》
📝《风格迁移》
📝《目标检测》
📝《图像增强》
📝《模型优化》
📝《模型实战部署》
📝《图像配准融合》
📝《数据集》
📝《高效助手》
📝《C++》


在这里插入图片描述

一、函数模版

函数模板是一种C++语言中提供的泛型编程工具,允许我们在编写函数时使用类型参数来支持多种数据类型,从而提高代码的复用性和可读性。

1.1 函数模版语法

以下是函数模板的基本语法和用法:

定义函数模板:

template <typename T>
T add(T a, T b) {
    return a + b;
}

参数解析:

template 是模板的关键字。
typename 或 class 是类型参数的声明关键字(两者等价)。
T 是类型参数,可以用任何合法的标识符代替。

1.2 函数模版例子

这里定义了一个函数模板 add,它可以接受两个相同类型的参数并返回它们的和。
编译器会在调用时根据传入的实参类型自动推导 T。

调用函数模板代码为:

int main() {
    cout << add(3, 5) << endl;          // 输出 8,T 推导为 int
    cout << add(2.5, 3.5) << endl;      // 输出 6.0,T 推导为 double
}

编译器根据实参的类型自动生成特定类型的函数。

如果需要显式指定类型,也可以下面方法调用:

cout << add<int>(3, 5) << endl;       // 显式指定 T 为 int

1.3 模版中多个类型参数

可以定义多个模板参数,用逗号分隔:

template <typename T1, typename T2>
void display(T1 a, T2 b) {
    cout << a << " and " << b << endl;
}

int main() {
    display(10, 3.14);     // T1 推导为 int,T2 推导为 double
    display("Hello", 42);  // T1 推导为 const char*,T2 推导为 int
}

1.4 代码

下面是一个完整的模版函数应用例子代码:

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

// 利用模版提供通用的交换函数
// template<class T>
template<typename T>            // 只要写了这一行代码,紧跟后面的函数就为模版函数
void mySwap(T& a,T& b)
{
    T temp = a;
    a = b;
    b = temp;
}

// 1、自动类型推导,必须推导出一致的数据类型T,才可以使用
void test01()
{
    int a = 10;
    int b = 20;
    char c = 'c';

    mySwap(a,b);       // 正确,可以推导出一致的T
    // mySwap(a,c);       // 错误,推导不出一致的T的类型

    cout << "a = " << a << endl;
    cout << "b = " << b << endl;

}

// 2、模版必须要确定出T的类型,才可使用
// template<class T>
template<typename T>
void func()
{
    cout << "func的调用" << endl;
}

void test02()
{
    // func();   // 错误,模版不能独立使用,必须确定出T的类型
    func<int>();  // 利用显示指定类型的方式,给T一个类型,才可以使用该模版
}

int main()
{
    test01();
    test02();

    system("pause");
    return 0;
    
}

运行代码输出见下:

在这里插入图片描述

二、数组排序案例

2.1 需求

利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序;

排序规则从大到小,排序算法为选择排序;

分别利用char数组和int数组进行测试。

2.2 实现

2.2.1 排序算法

排序算法为降序,实现思想为通过遍历数组中数据,先假定一个最大值max索引,与数组中后面数据比较,如果max索引对应的数据小于后面的数据,则交换数据,直至遍历完数组中所有数据。

排序算法的代码见下:

// 排序算法
template<typename 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下标的元素才是真正的最大值
            if (arr[max] < arr[j])
            {
                max = j;  // 更新最大值下标
            }
        }
        if (max != i)
        {
            // 交换max和i下标元素
            mySwap(arr[max],arr[i]);
        }
    }
}

2.2.2 交换函数的模版

交换函数模版代码见下:

// 交换函数的模版 
template<class T>
void mySwap(T&a,T&b)
{
    T temp = a;
    a = b;
    b = temp;
}

2.2.3 打印输出数组数据模版

重新排序后需要将数组中数据输出查看,将输出封装在printArray()函数模版中,代码见下,这一步用到了上面:1.3 模版中多个类型参数。

// 打印数组模版
template<typename T>
void printArray(T arr[],int len)
{
    for (int i = 0; i < len; i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}

2.2.4 测试char数组

char数组的测试代码见下:

void test01()
{
    // 测试char数组
    char charArr[] = "badcfe";
    int num = sizeof(charArr) / sizeof(char);
    mySort(charArr,num);
    printArray(charArr,num);
}

2.2.5 测试int数组

int数组测试代码见下:

void test02()
{
    //测试 int数组
    int intArr[] = {8,6,4,2,3,9,7,1};
    int num = sizeof(intArr) / sizeof(int);
    mySort(intArr,num);
    printArray(intArr,num);
}

2.3 完整实现代码

2.2小节中各个模块代码整合后的完整代码见下:

2.3.1 代码

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

/*
案例描述:
利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序
排序规则从大到小,排序算法为选择排序
分别利用char数组和int数组进行测试
*/

// 交换函数的模版 
template<class T>
void mySwap(T&a,T&b)
{
    T temp = a;
    a = b;
    b = temp;
}

// 排序算法
template<typename 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下标的元素才是真正的最大值
            if (arr[max] < arr[j])
            {
                max = j;  // 更新最大值下标
            }
        }
        if (max != i)
        {
            // 交换max和i下标元素
            mySwap(arr[max],arr[i]);
        }
    }
}

// 打印数组模版
template<typename T>
void printArray(T arr[],int len)
{
    for (int i = 0; i < len; i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}

void test01()
{
    // 测试char数组
    char charArr[] = "badcfe";
    int num = sizeof(charArr) / sizeof(char);
    mySort(charArr,num);
    printArray(charArr,num);
}

void test02()
{
    //测试 int数组
    int intArr[] = {8,6,4,2,3,9,7,1};
    int num = sizeof(intArr) / sizeof(int);
    mySort(intArr,num);
    printArray(intArr,num);
}

int main()
{
    test01();
    test02();

    system("pause");
    return 0;
    
}

2.3.2 输出

运行上面2.3.1代码,降序后的结果见下:

在这里插入图片描述

三、模版的局限性

模型的通用性并不是万能的。

下面代码中将string类型和int类型自定义为Person数据类型,如果直接调用函数模版会出错,需要在调用的函数前加template<> ,见下:
在这里插入图片描述

3.1 代码

自定义数据类型及调用函数模版示例代码见下:

// 模版的局限性
#include <iostream>
using namespace std;
#include <string>

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;
    }
}

// 具体化,显示具体化的原型,以template<>开头,并通过名称来指出类型
// 具体化优先于常规模版

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 test01()
{
    int a = 10;
    int b = 20;
    // 内置数据类型可以直接使用通用的函数模版
    bool ret = myCompare(a,b);
    if (ret)
    {
        cout << "a==b" << endl;
    }
    else
    {
        cout << "a != b" << endl;
    }
}

void test02()
{
    Person p1("Tom",10);
    Person p2("Tom",11);

    // 自定义数据类型,不会调用普通的函数模版
    // 可以创建具体化的Person数据类型的模版,用于特殊处理这个函数

    bool ret = myCompare(p1,p2);
    if (ret)
    {
        cout << "p1 == p2" << endl;
    }
    else
    {
        cout << "p1 != p2" << endl;
    }
}

int main()
{
    // test01();
    test02();

    system("pause");
    return 0;
    
}

3.2 输出

运行3.1中代码,输出见下:

在这里插入图片描述

四、总结

以上就是C++中函数模版语法及数组排序案例实现方法,希望能帮到你! 本人参考学习的是黑马程序员,仅作为笔记记录。

感谢您阅读到最后!😊总结不易,多多支持呀🌹 点赞👍收藏⭐评论✍️,您的三连是我持续更新的动力💖

关注下面「视觉研坊」,获取干货教程、实战案例、技术解答、行业资讯!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

视觉研坊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值