function7-模板
前言
重载回顾完之后
虽然说让一个函数名有了多个功能,但是每次都要多写一个函数还是挺麻烦的。
而模板功能是为了提升复用性的功能。
引用
关键字:
- template
正文
1 | int Ave(int a, int b, int c){ |
假如有这么个函数是求三个数的平均值,抛开类型,算法逻辑是相同的操作。重载也合理。
但是如果要对每一个类型都写一个这样的函数,就会变得很麻烦。
1 | template <typename type> type Ave(type a, type b, type c){ |
typename 后面跟的名称就像是自定义的关键词auto一般,后面写的函数使用这个变量名,就代表他是这个类型的函数
使用起来也很方便:
char类型也没问题,你用什么类型的参数他就会返回什么类型的值:
1 | template <typename type> |
既然说type是一个类型名,那么其实也可以在模板里面用它来定义变量。
甚至引用或者指针也ok。
指定模板类型
既然模板可以自适应,又为啥会用到指定?原因也就是形参类型不一的时候,没法主动去转换,需要人为干预。
1 | template <typename type> |
当参数不一致的时候: 编译器就会给出错误提示std::cout << Ave<int>(26, 78.9f, 25.8f) << std::endl;
当指定类型之后:
能看到这个函数模板就变成int的类型的函数了。
指针引用
1 | template<typename T> |
可看到被实例化成int*类型的函数了,但其实传递地址没有进行很好的处理,所以指很有可能是错的。
可当传递是引用时,发现并没有实例化成引用类型,而是普通的int类型。
而且const好像也不当回事:
函数模板重载
在经过一些例子尝试后,发现模板对于普通的类型转换是没有问题的,但是对于指针相关的操作可能就会有点不灵清。
就拿之前指针的问题,返回值甚至不是大的一方,只是单纯的返回了a。
解决的方法就是针对模板之外的情况附带一个指定的:
1 | template<typename T> |
可以看到输出正常了,也匹配到了后面指针那个模板:
但是倒霉的又来了,我们这里的指针函数是int类型的,就失去了模板之前自动根据参数识别的情况,但是可以用函数重载去弥补一些损失
1 | template<typename T> |
重载的时候就到了,不过要记住优先级,函数重载的优先级大于函数模板
1 | template<typename T> |
不相信的就自己动手,看看匹配到了那个:
如果是模板的话函数名后会有一个<>
符号去匹配类型:
然后就是模板的重载,函数的重载是通过参数比较的,模板是否也相同
1 | template <typename type> |
报错来得很快,直接说他重复了。
我们将其变化一下:
1 | template <typename type> |
可以看到调用的时候明显就区分开了:
结语
函数重载能理解,模板重载就没啥太大问题,性质差不多。除了模板还有个例外情况可以写。