模板初阶【C++】

liuyunluoxiao 2024-06-25 09:05:06 阅读 99

文章目录

模板的作用模板的原理模板分为两大类——函数模板和类模板函数模板语法函数模板实例化模板函数的方式模板函数的类型转换既有函数模板又有已经实现的函数,会优先调用哪一个?

类模板语法模板类实例化对象模板类的模板参数可以有缺省值类模板中的成员函数全函数模板模板类中的成员函数声明和定义分离

模板的作用

模板的主要作用是实现泛型编程,泛型编程即编写与类型无关的通用代码,是代码复用的一种手段

模板就是泛型编程的基础。

我们经常使用的交换函数就可以使用泛型编程来进行编写,这样可以大大减少重复的代码

一般编写方式

在这里插入图片描述

可以发现上图的三个函数除了参数类型不一样,其他的都是一样的重复的代码太多了,这个时候就可以考虑使用模板进行编写了


模板编写方式:

在这里插入图片描述

此时编译器就可以根据类型的不同实例化出不同的函数


模板的原理

模板就如其名字一样,就像一个冰棍模具,把不同的果汁(类型)放进去就可以得到不同口味的冰棍,但是这些冰棍就只有口味不同,外形(代码逻辑)都是一样的。

如下图

在这里插入图片描述

编译器编译阶段,对于模板的使用,编译器会根据传入的实参类型来推演生成对应类型的函数以供

调用。


模板分为两大类——函数模板和类模板

函数模板

语法

template < typename/class T(自定义类型名), typename/class T,………>

函数模板定义

在这里插入图片描述


函数模板实例化模板函数的方式

只传实参(隐式调用)[让编译器自己根据实参类型]

在这里插入图片描述

既传实参又传类型(显示调用)[即自己指定模板使用的类型]

在这里插入图片描述

必须显式传类型的场景

即仅靠实参推演出的类型不够

在这里插入图片描述

此时就必须显式传类型

在这里插入图片描述


当模板类型个数和实参个数不同时,可能会类型不明

在这里插入图片描述

此时有3个解决方法

对实参进行强制类型转换

即 把函数调用方式改为: Add(a,(int)c)或者 Add((char) a,c),让参数类型统一。

显式传递模板参数

即 把函数调用方式改为Add<int>(a,c)或者Add<char>(a,c),让编译器知道模板参数是什么,先实例化出对应的函数之后,再传入实参,此时实参就会自动进行隐式类型转换

增加模板参数个数到于实参个数匹配

在这里插入图片描述


模板函数类型转换

使用实参类型推导模板参数时(隐式调用),不能隐式类型转换

显式调用时可以隐式类型转换


既有函数模板又有已经实现的函数,会优先调用哪一个?

例如下图这种情况:

在这里插入图片描述

此时分3种情况

如果调用普通函数不会发生类型转换,那就调用已经存在的普通函数

在这里插入图片描述

如果调用普通函数发生类型转换,而调用函数模板实例化的模板函数不会发生类型转换时,就调用模板函数

在这里插入图片描述

如果都发生类型转换,就调用已经存在的普通函数


类模板

语法

template < typename/class T(自定义类型名), typename/class T,………>

模板类的定义

在这里插入图片描述


模板类实例化对象

模板类实例化对象时只能显式传类型

此时<>加在类名后面

[<>必须要有,哪怕<>中不写类型]

在这里插入图片描述

在这里插入图片描述


模板类的模板参数可以有缺省值

在这里插入图片描述

类模板中的成员函数全函数模板

为什么?

因为类模板中的成员变量的类型是不确定的,成员函数是否使用了类模板的模板类型不确定

所以他没有办法像普通类的成员函数一样,在编译时就创建好了

而是跟函数模板一样需要编译器在运行过程中推演


模板类中的成员函数声明和定义分离

不能简单地直接类名+::

而是

模板类型声明+类中的成员函数的定义[注意此时类名后面还是要加<类型>,因为这样才是一个完整的类类型],这样类实例化对象的时候就可以推导出对应的成员函数的类型

在这里插入图片描述

由于模板类不完整,所以不能直接用它去限定作用域

即在类外实现成员函数等用::区限定时,不能直接限定,要先指定类型



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。