初识C++中的模板

当我们写交换两个变量内容的函数时,虽然有函数重载,但函数内容基本上都一样,这样显得有些麻烦了。C++ 中就提供了解决该问题的方法------模板。

泛型编程

泛型编程指的是编写与类型无关的通用代码,不指定具体数据类型,等到使用时再确定其类型。

泛型编程出现的意义就在于,使一段代码可以适配多种不同类型的数据,让我们不用重复写多个同样的代码。比如说对于不同类型数据的 Swap 交换函数,C++ 中就是靠模板来实现的。## 函数模板

函数模板定义的是一类函数,这类函数与参数类型无关,只有在特定情况下才会产生对应的函数。

一个函数模板定义的方式如下:template <typename 类型名(自定)>,其中类型的名称我们可以自己命名,通常是 T。

比如说我们定义函数 Swap 的函数模板:

cpp 复制代码
//函数模板
template <typename T>
void Swap(T& left, T& right)
{
	T tmp = left;
	left = right;
	right = tmp;
}

这就是一个函数模板了,当我们显式调用它或者传参调用该函数时,编译器才会根据该函数模板生成对应的函数。该过程就称为函数模板的实例化。

cpp 复制代码
int main()
{
  int x1 = 1,x2 = 2;
	//显式实例化
	//函数名后跟<>,内写类型
	//显式实例化的时候就调用该函数
	Swap<int>(x1, x2);

	double d1 = 3.14, d2 = 5.12;
	//隐式实例化
	Swap(d1, d2);

	return 0;
}

这是正常情况下,如果我们传过去的一个是 int 型,一个是 double 型,那么在类型匹配上都会产生冲突,第一个 T 匹配的是 int,第二个 T 变成了 double,产生了冲突,这时分两种情况:

  • 如果是隐式实例化,此时编译器就会报错,不会进入实例化阶段。
  • 如果我们已经显式实例化出了一个函数(如上),然后在显式实例化时就调用该函数(反之报错),编译器在传参时就会帮我们进行类型转换(double 转为 int),再调用这个函数。

函数调用优先级

如果我们已经定义了一个 Swap 函数,假设就是 int 类型,然后我们显式实例化出了一个 int 型的 Swap 函数,那么编译器会先调用哪个函数呢?

cpp 复制代码
void Swap(int& left, int& right)
{
	int tmp = left + 3;//做点区别
	left = right;
	right = tmp;
}

//函数模板
template <typename T>
void Swap(T& left, T& right)
{
	T tmp = left;
	left = right;
	right = tmp;
}

int main()
{

	int x1 = 1, x2 = 2;
	Swap<int>;
	Swap(x1, x2);
	cout<< x1 << ' ' << x2 << endl;
	return 0;
}

可以看到调用的是我们自己定义的函数,如果模板函数更匹配,编译器则会去调用模板函数。## 类模板

类模板的定义格式如下:template <class T>

比如说我们想定义不同的 Stack 类来存储不同类型的数据:

cpp 复制代码
//类模板
template <class T>
class Stack
{
public:
	Stack(int n = 4)
		:_array(new T[n])
		, _top(0)
		, _capacity(n)
	{

	}
	void Push(T& x)
	{
		_array[_top++] = x;
	}
	~Stack()
	{
	delete[] _array;
	}
private:
	T* _array;
	int _top;
	int _capacity;
};

然后我们就可以生成不同的 Stack 类,存储不同类型的数据了。

cpp 复制代码
int main()
{
	Stack<int> s1;
	Stack<char> s2;
	Stack<double> s3;
//这三个对象是不同的类型
	return 0;
}
相关推荐
Wang's Blog1 小时前
Java 项目实战: 交友项目 - SpringCloud 整合 Dubbo 的需求分析与模块规划
java·spring cloud·交友
程序员Linc1 小时前
ONNXOCRSharp 开源手记 02|v0.4.0 PDF识别
开发语言·pdf·c#·ocr·onnxocrsharp
回眸&啤酒鸭1 小时前
【回眸】HireKey 智能招聘全流程应用场景
开发语言·人工智能·python
云川之下1 小时前
【存储】搭建nfs 存储示例
开发语言·php
垆边人似月.1 小时前
华为题:合并区间
数据结构·c++·算法
哦虎!1 小时前
【JavaEE】文件操作IO
java
十年Java程序媛1 小时前
Redis 分布式锁 + GZIP 压缩缓存踩坑|高并发缓存真实线上复盘
java·开发语言·spring boot·redis·分布式·缓存·面试
低频电磁之道1 小时前
C++ 中有符号与无符号类型混用可能导致的问题
开发语言·c++
垆边人似月.2 小时前
华为题:滑动窗口最大值
数据结构·c++·算法