C++模板初阶

C++模板初阶

大家在做OJ题的时候可能看到过这种使用STL的样子:

其实这个就是我们今天要介绍的模板这个语法在STL中的应用

一.泛型编程

在介绍泛型编程的概念之前,先给大家看一下这个例子

比方说:我今天要分别实现int和int类型,double和double类型,char和char类型的Swap函数

那么我可能需要利用函数重载写出一下三份代码

cpp 复制代码
void Swap(int& a, int& b)
{
	 int tmp = a;
	 a = b;
	 b = tmp;
}
void Swap(double& a, double& b)
{
	 double tmp = a;
	 a = b;
	 b = tmp;
}
void Swap(char& a, char& b)
{
	 char tmp = a;
	 a = b;
	 b = tmp;;
}

这样也是可以做到的

但是这样好不好呢?

二.函数模板

1.概念

2.实例

因此,我们就可以这样优化那份Swap函数了

cpp 复制代码
//typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)
//template<typename T>//T:type
template<class T>//T:type
void Swap(T& a, T& b)
{
	T tmp = a;
	a = b;
	b = tmp;
}
int main()
{
	int a = 0, b = 1;
	Swap(a, b);//模板的实例化
	double c = 2.1, d = 3.1;
	Swap(c, d);
	char e = 'a', f = 'b';
	Swap(e, f);
	return 0;
}

下面问题来了,这三次调用Swap函数调用的是同一个函数吗?

答案是:并不是,为什么呢?

这就涉及到下面的函数模板的原理了

3.原理


因此,如果我的这个函数调用让编译器无法推演出T的类型,也就是下面这种情况,编译器就会报错

(这里我使用Add这个函数来为下面做例子,关于为什么不用Swap函数我会在介绍的时候一并说明的)

注意:在模板中,编译器一般不会进行隐式类型转换操作,

因为一旦转化出问题,编译器就需要背黑锅

能不能通过某种手段来解决这种错误呢?

可以使用下面介绍的函数模板的实例化

4.函数模板的实例化

1.隐式实例化

我们可以这样去做:

这里我通过强制类型转换

分别将i和d这两个变量转换为int和double类型,成功完成了相加

但是:

那么为什么Swap函数就不可以呢?

我们之前在C++入门-引用中提到过:

那么接下来我们来看第二种方法:显式实例化

2.显式实例化

这里<int>里面的int就是告诉编译器,这个T的类型就是int,同理<double>也是如此

那么这种方法能不能解决Swap呢?

当然不行啦,因为我这个Swap的报错是权限放大导致的报错,不是T的类型无法推演出来所导致的报错

注意:

1.当我们无法通过传参的方式来让函数模板推演出T的类型的时候,才是显式实例化真正的用武之地:

2.模板参数列表也可以定义很多T

5.模板参数的匹配原则

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

  1. 对于非模板函数和同名函数模板:

如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例

如果模板可以产生一个具有更好匹配的函数 , 那么将选择模板

  1. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

三.类模板

1.类模板的引出

我们在学习数据结构的时候经常会用到

cpp 复制代码
typedef int STDateType;

等等这样的typedef

但是typedef也不能解决所有问题:

比如这种问题:

如果我今天定义两个栈对象,一个存int,一个存double,这种情况下typedef就无法解决了,

那么该怎么办呢?

这个时候就要用到类模板了

2.实例

语法形式跟函数模板类似

不过:

也就是说这里的真正的类是

Stack<int> Stack<double> Stack<char> Stack<A>

以上就是C++模板初阶的全部内容,希望能对大家有所帮助!

相关推荐
Maple_land36 分钟前
Linux进程第八讲——进程状态全景解析(二):从阻塞到消亡的完整生命周期
linux·运维·服务器·c++·centos
ajassi20001 小时前
开源 C++ QT QML 开发(十一)通讯--TCP服务器端
c++·qt·开源
lyp90h1 小时前
高效SQLite操作:基于C++模板元编程的自动化封装
c++
minji...1 小时前
Linux相关工具vim/gcc/g++/gdb/cgdb的使用详解
linux·运维·服务器·c++·git·自动化·vim
_OP_CHEN1 小时前
C++基础:(九)string类的使用与模拟实现
开发语言·c++·stl·string·string类·c++容器·stl模拟实现
爱编程的化学家2 小时前
代码随想录算法训练营第27天 -- 动态规划1 || 509.斐波那契数列 / 70.爬楼梯 / 746.使用最小花费爬楼梯
数据结构·c++·算法·leetcode·动态规划·代码随想录
数字化顾问3 小时前
C++分布式语音识别服务实践——架构设计与关键技术
c++
智能化咨询3 小时前
C++分布式语音识别服务实践——性能优化与实战部署
c++
ajassi20003 小时前
开源 C++ QT QML 开发(十四)进程用途
c++·qt·开源
闻缺陷则喜何志丹3 小时前
【C++贪心】P8769 [蓝桥杯 2021 国 C] 巧克力|普及+
c++·算法·蓝桥杯·洛谷