目录
写在前面的话
hello小伙伴们大家好啊!欢迎来到小库森为你精心打造的博客!今天小库森为大家带来的是有关C++模板的内容。其实对于模板这个概念,我们很多小伙伴都是有的,是的,正如大家所理解的一样,C++中的模板同样的。那么我们废话不多说,直接进入主题~
一,函数重载
那么首先,我们需要了解一下之前我们说过的,有关重载函数的内容。
我们知道,对于功能差不多的函数,因为函数参数的唯一性,所以我们不能功能类似的函数写为一个函数,但是同时我们发现,其实对于有一些重载函数来说,看起来是很冗余的。
除此之外,我们可以想到的是,因为大多数的重载函数都是我们将最开始的函数复制粘贴,然后再将其进行修改,那么如果我们不小心将最开始的函数写错了,那么就可能导致后面的函数都出错,这样也就意味着我们对于重载函数的可维护性是不高的。
那么我们理所当然的,会去想着有一种方法,可以解决冗余以及没法很好的维护的问题。
是的,这个办法就是函数模板。
二,函数模板
2.1什么是函数模板
函数模板:函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
2.2模板函数定义
也就是说,函数模板本身就是一个模板,但是没有类型的要求,所有的类型都是由参数决定的,当我们传递了参数之后,模板会根据参数的类型去决定该函数该有的类型。
如下图所示:
那么首先,对于函数模板来说,首先就是模板的格式:template <typename T> 或者 template <class T>,然后后面紧接着就是函数体,因为参数类型是由传递的实参决定的,所以我也不会显示的写出来,而是使用 T 来替代。
那么我们在函数调用的时候,如下图所示,就可以传递同类型的值去调用模板函数:
那么当然,我们不能忽略的是,每次为了方便我们使用,我们都是将标准民命空间使用 using 展开了。所以就有可能导致库中的函数和我们自己定义的函数名出现冲突。
2.3模板实例化
2.3.1隐式实例化
其实上面我们所说的,属于隐式实例化,因为我们并没有在传递实参的时候,指定参数类型,而是模板自己通过实参去判断是那种类型,然后再实例化出一个函数。
2.3.2显示实例化
相对来说,显示实例化应该就是在传递实参的时候,显示的将参数的类型指定了,那既然隐式实例化可以实现了,为什么需要显示实例化呢?我们看一下如下所示的实参传递:
我们发现这里报错了。那具体的原因呢,就是因为我们传递了两个类型不一样的参数。因为在函数模板中,它只有一个类型 T,没法识别两个参数类型。那么怎样去解决呢?
这里我们提出了两种解决方法:首先是自己强转,其次是使用显示实例化解决。
那么对于以上两种形式的修改,对于用户自强转,可以理解。对于实例化的方法来说,也就是在函数后面加上一对尖括号,然后再将参数类型加上。那么在现实中,我们一般会选择后者。
三,类模板
3.1类模板定义
前面我们了解了有关模板函数的内容。那么同样的,如果我们对于类也有同样的需要,此时我们就可以实现类模板,而对于类模板来说,它的功能以及结构是和函数模板差不多的。如下图所示:
那么我们看到,我们使用栈类的模板来演示,可以看到 template 命名依旧是一样的,而我们需要使用模板更换内容的地方就是每一次实参类型都不同时,需要实例化的地方。如上图所示,首先在构造函数中,在每次申请空间时,需要使用;以及在有关函数调用时,也需要使用;当然,不可或缺的是在成员变量的声明时,也需要使用。
3.2函数在类模板外实现
但是这里需要注意的是,类模板的类型是 类名<T>,因为如果我们在类外使用函数时,需要在函数返回值之后加上模板参数列表。如下图所示:
3.3类模板实例化模板类
那么不同于函数模板,对于类模板的实例化只有一种形式。因为我们每次都是选择一种类型去实例化我们的函数,所以类模板的实例化只能通过显示实例化去实现,如下图所示:
好的,那么对于C++中的模板我们到这里就结束啦!如有问题,还请指正呀!