泛型编程

156 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

【写在前面】

之前在学数据结构时就说过,C 语言没有实现数据结构的库,非常的麻烦,为什么 C 语言没有这样的库呢,因为它不支持泛型编程。所以在 C++ 中它支持了泛型编程,支持了模板 —— 函数模板、类模板。 这里只是模板的入门,只为了先入门 STL。后面 C++ 初阶会对模板进行进阶的学习。

一、泛型编程

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。

在这里插入图片描述

如何实现一个通用的交换函数 ❓

void Swap(int& left, int& right)
{
	int temp = left;
	left = right;
	right = temp;
}
void Swap(double& left, double& right)
{
	double temp = left;
	left = right;
	right = temp;
}
int main()
{
	int a = 0, b = 1;
	double c = 1.1, d = 2.2;
	Swap(a, b);
	Swap(c, d);
	
	return 0;
}

📝说明

虽然能够达到目的,但是也有缺陷:

  1. 重载的函数仅仅只是类型不同,代码的复用率比较低,只要有新类型出现时,就需要增加对应的函数
  2. 代码的可维护性比较差,一个出错可能所有的重载都出错

能否告诉编译器一个模子,让编译器根据不同的类型利用该模子生成代码 ❓

在 C++ 中,也能够存在这样一个模具,通过给这个模具中填充不同材料 (类型),来获得不同材料的铸件 (生成具体类型的代码),那将会节省许多头发。巧的是前人早已将树栽好,我们只需在此乘凉。

image.png

二、函数模板

💦 函数模板的概念

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

💦 函数模板的格式

template<typename T1, typename T2,......,typename Tn> 返回值类型 函数名(参数列表){}

template<typename T>
template<class T>

📝说明

对于 T 我们可以任意起,如 L、K、Compare 等,这个名称是自己取的,但是一般要符合意境,前期一般喜欢用 T (Type 的意思)。

注意 typename 是用来定义模板参数的关键字,也可以使用 class (这里不能用 struct 代替 class)。typename 是新增的,好多地方都习惯用 class,包括后面学习的 STL (它的源码里都用的 class),现阶段可以认为 typename 和 class 没有区别,到后面会有一点区别,学到了再看。

函数模板实现交换 ❓

//如果写了对应的函数,那么它依然会去调用,但是没必要
/*void Swap(int& left, int& right)
{
	int temp = left;
	left = right;
	right = temp;
}*/
template<class T>
void Swap(T& x1, T& x2)
{
	T tmp = x1;
	x1 = x2;
	x2 = tmp;
}
int main()
{
	int a = 0, b = 1;
	double c = 1.1, d = 2.2;
	int* p1 = &a, *p2 = &b;
	Swap(a, b);
	Swap(c, d);
	Swap(p1, p2);
	return 0;
}

📝说明

这里就可以知道它可以针对所有类型完成交换工作。

那它一个函数能完成这里几种函数的功能吗 ???