• C++---模板


    模板

    顾名思义,像PPT模板一样,根据不同的需要,往里面添加不同的内容。
    C++编程中与类与对象并列的另一大分支就是泛型编程,泛型编程主要利用的技术就是模板。提供两种模板机制:类模板和函数模板。

    函数模板

    作用

    建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。

    语法

    template<typename AnyType>
    
    • 1

    解释

    template–声明创建一个模板
    typename–给创建的模板命名
    Anytype–类型命名
    关键字template和typename是必需的,除非typename用class代替。

    代码

    #include
    using namespace std;
    //声明一个函数模板
    //T代表通用数据模型
    template<typename T>
    void Swap(T& a, T& b)
    {
    	T temp;
    	temp = a;
    	a = b;
    	b = temp;
    }
    
    void test01()
    {
    	int a = 20, b = 30;
    	double c = 1.23, d = 3.56;
    	//1、自动类型推导
    	//2、显示指定类型
    	Swap(a, b);
    	Swap<int>(a, b);
    	cout << "a=" << a << endl;
    	cout << "b=" << b << endl;
    	Swap(c, d);
    	cout << "c=" << c << endl;
    	cout << "d=" <<d << endl;
    }
    int main()
    {
    	test01();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    函数模板使用技巧

    • 在自动推导类型的时候,必须要推导出一致的类型才能使用;(上段代码就不可以交换int 和double);
    • 模板必须要确定出T的类型,才可以使用。

    函数模板案例

    案例描述:

    • 利用函数模板封装一个排序的函数,可以的不同数组类型数组进行排序
    • 降序排序,排序算法为选择排序
    • 分别利用char数组和int数组进行排序
    #include
    using namespace std;
    template<typename T>
    void Swap(T& a, T& b)
    {
    	T temp;
    	temp = a;
    	a = b;
    	b = temp;
    }
    template<typename T>
    void Sortselction(T nums[], int len)
    {
    	int MaxIndex = 0;
    	for (int i = 0; i < len - 1; i++)
    	{
    		MaxIndex = i;
    		for (int j = i + 1; j < len; j++)
    		{
    			if (nums[MaxIndex] < nums[j])
    			{
    				MaxIndex = j;
    			}
    		}
    		swap(nums[MaxIndex], nums[i]);
    	}
    }
    //打印函数模板
    template<typename T>
    void Print(T arr[], int len)
    {
    	for (int i = 0; i < len; i++)
    		cout << arr[i] << "  ";
    	cout << endl;
    }
    void test01()
    {
    	int arr[5] = { 4,7,2,5,90 };
    	char chaArr[] = "badcfe";
    	Sortselction(chaArr, 6);
    	Print(chaArr, 6);
    	Sortselction(arr, 5);
    	Print(arr, 5);
    }
    int main()
    {
    	test01();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    模板重载

    需要对多个不同类型使用同一种算法的函数时,可使用模板,重载的模板函数参数列表必须不同。
    示例:

    #include
    using namespace std;
    const int dim=8;
    template<typename T>
    void Swap(T& a, T& b)
    {
    	T temp;
    	temp = a;
    	a = b;
    	b = temp;
    }
    //函数模板重载,实现数组交换
    template<typename T>
    void Swap(T a[], T b[],int len)
    {
    	for (int i = 0; i < len; i++)
    	{
    		T temp = a[i];
    		a[i] = b[i];
    		b[i] = temp;
    	}
    }
    void show(int a[],int n)
    {
    	for (int i = 0; i < n; i++)
    	{
    		cout << a[i] << " ";
    	}
    	cout << endl;
    }
    int main()
    {
    	int d1[dim] = { 0,7,0,4,1,7,7,6 };
    	int d2[dim] = { 0,7,2,0,1,9,6,9 };
    	Swap(d1, d2, dim);
    	show(d1,dim);
    	show(d2, dim);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    函数模板的局限性

    编写的函数很有可能无法处理某些类型,如果我们交换两个结构体中的内容,上述代码中的Swap函数肯定是无法执行功能的。C++为特定类型提供了具体化的模板定义。
    假如定义了以下结构:

    struct job
    {
    	char name[40];
    	double salary;
    	int floor;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    假如希望交换两个模板的内容,原来的模板用以下代码来交换:

    temp = a;
    	a = b;
    	b = temp;
    
    • 1
    • 2
    • 3

    C++允许将一个结构赋给另一个结构,因此T是一个job结构,上述代码也适用,但是如果想交换salary和floor成员,而不交换name,则需要不一样的代码,但是由于Swap参数的保持不变(两个job结构的引用),因此无法用模板重载实现。
    但是可以利用显式具体化来实现功能,当编译器找到与函数调用匹配的具体定义时,将使用该定义,不再寻找其他模板函数。

    显式具体化

    语法:template<>void Swap(job& j1,job& j2)
    示例:

    #include
    using namespace std;
    template<typename T>
    void Swap(T& a, T& b);
    struct job
    {
    	char name[40];
    	double salary;
    	int floor;
    };
    void show(job& j);
    //显示具体化
    template<> void Swap<job>(job& j1, job& j2);
    int main()
    {
    	job sue = { "Susan Yaffee",53000.60,7 };
    	job sidney = { "Sidney Taffee",78060.72,9 };
    	cout << "Befor job swapping:\n";
    	show(sue);
    	show(sidney);
    	cout << "After job swapping:\n";
    	Swap(sue, sidney);
    	show(sue);
    	show(sidney);
    }
    template<typename T>
    void Swap(T& a, T& b)
    {
    	T temp;
    	temp = a;
    	a = b;
    	b = temp;
    }
    void show(job& j)
    {
    	cout << j.name << ": $" << j.salary << " on floor " << j.floor << endl;
    }
    template<>void Swap<job>(job& j1, job& j2)
    {
    	//交换salary和floor
    	Swap(j1.salary, j2.salary);
    	Swap(j1.floor, j2.floor);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
  • 相关阅读:
    vue-cli解决IE浏览器chunk-vendors.js 提示sockjs-client错误
    linux--发展史与环境
    Retrofit原理 一篇文章就够了
    自定义结构体的json序列化
    【JavaScript】五个常用功能/案例:判断特定结尾字符串 | 获取指定字符串 | 颜色字符串转换 | 字符串转驼峰格式 | 简易购物车
    PPLiteSeg训练自己的数据集实现自动驾驶并爆改制作成API可供其他Python程序调用实时语义分割(超低延时)
    层次聚类分析及代码实现
    Apache SeaTunnel本地源码构建编译运行调试
    (一)MySQL_数据库概述技术总结
    win11 L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误
  • 原文地址:https://blog.csdn.net/wh22141334/article/details/126190314