C++泛型编程之函数模板浅谈

目录

为什么要用函数模板

一、宏定义的优缺点

二、函数的优缺点

三、函数模板

1、函数模板有两个关键字template和typename

2、函数模板定义多个不同数据类型

3、函数模板的调用

4、函数模板实现排序等算法

5、函数模板优点与总结

6、完整的示例代码


 

为什么要用函数模板

为什么要使用函数模板?顾名思义就是一个通用模板,可以直接套入使用。在以往C语言的编程中,我们可能会利用宏定义去实现这模板技术,在C++基础编程中可能就是用函数去实现了,可能在很多时候类型不同,就有可能需要定义多个不同类型的函数,去实现同一功能,这或许就让我们联想到函数重载,两者有利有弊,在C++中有更好的方案可以选择:函数模板

一、宏定义的优缺点

(1)优点:适合代码复用,实现模板,可以适用于任何类型;

(2)缺点:只进行代码的替换,没有进行类型安全检测,不是真正的函数调用。

二、函数的优缺点

(1)优点:可以作为真正的函数调用,具有类型安全检测;

(2)缺点:只实现单一数据类型的功能实现,不同数据类型需要多次定义不同类型的函数,不利于代码复用。

三、函数模板

1、函数模板有两个关键字template和typename

(1)template:声明编译器开始进行泛型编程;

(2)typename:声明该函数模板所泛指任意的数据类型。

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

2、函数模板定义多个不同数据类型

函数模板不单单可以定义同一种数据类型,它也支持多种数据类型的声明和实现,只要区分T1,T2...等参数的命名即可。

//数组遍历打印
template <typename T1, typename T2>
void Printfln(T1 a[], T2 len)
{
	for (T2 i = 0; i < len; i++)
	{
		std:cout << a[i] << ", ";
	}
	std::cout << std::endl;
}

3、函数模板的调用

函数模板的调用可以分为两种:编译器自动推导类型调用具体类型显示调用。

//编译器自动推导类型调用
add(a, b);

//具体类型显示调用
add<int>(a, b);

4、函数模板实现排序等算法

在项目开发中,我们经常用函数模板来进行各种算法的封装,让各种数据类型与之匹配:

//冒泡排序
template <typename T>
void BubbleSort(T a[], int len)
{
	for ( int i = 0; i < (len - 1); i++ )
	{
		for (int j = 0; j < (len - i - 1); j++)
		{
			if (a[j] > a[j + 1])
			{
				T temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
			}
		}
	}
}

5、函数模板优点与总结

(1)优点:不需要考虑数据类型,实现代码复用;

(2)函数模板的关键字有两个,调用方式也有两种;

(3)可以定义多个不同数据类型参数;

(4)实现代码复用。

6、完整的示例代码

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

//变量交换
template <typename T>
void Swap(T &a, T &b)
{
	T temp = a;
	a = b;
	b = temp;
}

//冒泡排序
template <typename T>
void BubbleSort(T a[], int len)
{
	for ( int i = 0; i < (len - 1); i++ )
	{
		for (int j = 0; j < (len - i - 1); j++)
		{
			if (a[j] > a[j + 1])
			{
				T temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
			}
		}
	}
}

//定义多个泛型变量
template <typename T1, typename T2>
void Printfln(T1 a[], T2 len)
{
	for (T2 i = 0; i < len; i++)
	{
		std:cout << a[i] << ", ";
	}
	std::cout << std::endl;
}

int main()
{
	int a = 1, b = 2;
	std::cout << "a: " << a << ", b: " << b << std::endl;
	//编译器自动推导类型调用
#if 0
	Swap(a, b);
#endif
	//具体类型显示调用
	Swap<int >(a, b);
	std::cout << "a: " << a << ", b: " << b << std::endl;

	//冒泡排序测试
	std::cout << std::endl;
	std::cout << "冒泡排序测试" << std::endl;
	int arry_a[6] = {7, 8, 4, 6, 2, 1};
	Printfln(arry_a, 6);
	BubbleSort(arry_a, 6);
	Printfln(arry_a, 6);

	float arry_b[5] = { 0.9, 1.8, 8.8, 6.6, 3.8 };
	Printfln(arry_b, 5);
	BubbleSort(arry_b, 5);
	Printfln(arry_b, 5);

	string arry_s[3] = {"lwx", "monkey", "China"};
	Printfln(arry_s, 3);
	BubbleSort(arry_s, 3);
	Printfln(arry_s, 3);		//根据字典形式排序

	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值