函数模板和类模板

前言:各位老铁好,今天来分享函数模板和类模板的知识,这个算是一个小知识,但这个小知识非常重要,相信学C++的各位老铁一定听过STL这个名词,那么STL是什么呢?它与我们今天分享的这个函数模板和类模板有什么关系呢?

首先我们要明白STL全称是Standard Template Library,是c++的标准模板库,顾名思义,STL既然是一个模板库了,今天我们将的就是模板,所以我们可以知道今天分享的内容是为后面学习STL打基础的,好了,接下来进入正题了。

函数模板

1.概念:函数模板就表示一个函数家族,里面存着的模板适用于各种类型的参数,所以函数模板与函数的参数类型无关,函数模板会根据实参传过来的类型进行生成对应的函数类型版本。

2.语法格式:

template<class T>//这个是函数模板必须要写的开头
//class关键字可以换成typename关键字,但不能换成struct关键字
void Swap(T& left, T& right)
{
	T tmp = right;
	right = left;
	left = tmp;
}

这个就是一个交换函数的模板,你可以传任何类型的数据进行交换。
我们来看看能不能实现交换吧

template<class T>//这个是函数模板必须要写的开头
//class关键字可以换成typename关键字,但不能换成struct关键字
void Swap(T& left, T& right)
{
	T tmp = right;
	right = left;
	left = tmp;
	cout << left << " " << right;
	cout << endl;
}

int main()
{
	int a = 0, b = 1;
	Swap(a, b);
	double c = 1.1, d = 2.2;
	Swap(c, d);
	string ch1 = "abc";
	string ch2 = "def";
	Swap(ch1, ch2);
	return 0;
}

在这里插入图片描述

3.函数模板的实例化

用不同类型的参数使用函数模板表示对函数模板的实例化,函数模板的实例化分为显示实例化和隐式实例化。

隐式实例化:让编译器通过实参来判断参数的类型,从而生成相对应得代码(上面得例子就是隐式实例化)

显示实例化:在调用时,在函数名后的<>中指定模板参数的实际类型

我们来看看下面这个代码

template<class T>//这个是函数模板必须要写的开头
//class关键字可以换成typename关键字,但不能换成struct关键字
void Swap(T& left, T& right)
{
	T tmp = right;
	right = left;
	left = tmp;
	cout << left << " " << right;
	cout << endl;
}

int main()
{
	int a = 0;
	char b = 'a';
	Swap(a, b);
	
	return 0;
}

可以猜猜这个代码是正常运行还是报错,我们来看看结果吧
在这里插入图片描述
编译器直接报错了,这是为什么呢?我们可以看到a和b是不同类型的数据,现在我们要拿这两个不同类型的数据进行实例化,但我们可以发现,Swap的参数只有一个T类型,编译器不知道是实例化成int类型还是char类型 ,所以编译器直接就报错了,有的老铁会说编译器不是会自动从低类型转化为高类型吗?的确编译器在算术运算时会从低类型转化为高类型,但在模板函数里面,编译器一般不会进行隐式类型的转化,毕竟转化出了问题,编译器就要背锅了。

那么我们如何能解决这个问题呢?有两种方法,一是直接进行强制类型转化,二是使用显示实例化

**强制转化类型**
template<class T>
T ADD(const T& left, const T& right)
{
	return left + right;
}

int main()
{
	int sum = 0;
	int a = 1;
	double b = 1.1;
	sum = ADD(a, (int)b);
	cout << sum << endl;
	return 0;
}

在这里插入图片描述

**显示实例化**
template<class T>
T ADD(const T& left, const T& right)
{
	return left + right;
}

int main()
{
	int sum = 0;
	int a = 1;
	double b = 1.1;
	sum = ADD<int>(a, b);//这里表示将a和b都当成int类型,编译器会自动把b转化为int类型
	cout << sum << endl;
	return 0;
}

在这里插入图片描述

4.模板函数的匹配原则

1.一个非模板函数可以和一个同名的模板函数同时存在,且该模板函数还可以实例化为非模板函数

template<class T>
T ADD(const T& left, const T& right)
{
	return left + right;
}
int ADD(const int a, const int b)
{
	return a + b;
}

int main()
{
	int sum = 0;
	int a = 1;
	double b = 1.1;
	sum = ADD(a, (int)b);//这里表示将a和b都当成int类型,编译器会自动把b转化为int类型
	cout << sum << endl;
	return 0;
}

在这里插入图片描述

对于同名模板函数和非模板函数,如果其他条件相同,编译器会优先调用非模板函数,这样毕竟效率高。

类模板

1.类模板定义:

template<class T>
class Vector//vector不是具体的类,而是一个可以生成任何类型的类的模具
{
public:
	Vector(size_t capacity = 10)
		: _pData(new T[capacity])
		, _size(0)
		, _capacity(capacity)
	{}
private:
	T* _pData;
	size_t _size;
	size_t _capacity;
};

那么该如何在模板中实现在类中声明,在类外定义,其实也和非模板实现在类中声明,在类外定义差不多,

template<class T>
class Vector//vector不是具体的类,而是一个可以生成任何类型的类的模具
{
public:
	Vector(size_t capacity = 10)
		: _pData(new T[capacity])
		, _size(0)
		, _capacity(capacity)
	{}
	// 使用析构函数演示:在类中声明,在类外定义。
	~Vector();
private:
	T* _pData;
	size_t _size;
	size_t _capacity;
};

//注意在类外定义时需要加模板参数列表
template<class T>
Vector<T>::~Vector()//Vector<T>才是类型
{
	if (_pData)
		delete[] _pData;
	_size = _capacity = 0;
}

2.类的实例化:

template<class T>
class Vector//vector不是具体的类,而是一个可以生成任何类型的类的模具
{
public:
	Vector(size_t capacity = 10)
		: _pData(new T[capacity])
		, _size(0)
		, _capacity(capacity)
	{}
	// 使用析构函数演示:在类中声明,在类外定义。
	~Vector();
private:
	T* _pData;
	size_t _size;
	size_t _capacity;
};

//注意在类外定义时需要加模板参数列表
template<class T>
Vector<T>::~Vector()//Vector<T>才是类型
{
	if (_pData)
		delete[] _pData;
	_size = _capacity = 0;
}

int main()
{
	//类模板实例化(只有实例化了才创建出一个真正的类)
	Vector<int> a;//Vector<int>才是类的类型,Vector只是类名

	return 0;
}

总结:

今天和大家分享的两个小知识,函数的模板和类的模板,它们有着共同点也有不同点,希望各位老铁看了这篇文章能有所收获。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

平平无奇。。。

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

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

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

打赏作者

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

抵扣说明:

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

余额充值