当前位置: 首页 > news >正文

【C++】模板初阶,了解函数模板和类模板的使用一些可能出现的问题

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
在这里插入图片描述模板可以有函数模板和类模板

文章目录

  • 一、模板简介
  • 二、模板的声明和定义
    • 1.模板的声明
    • 2.函数模板的定义
    • 3.定义一个类模板
  • 三、模板工作原理
  • 四、函数模板
  • 五、函数模板的实例化
    • 1.隐式实例化
    • 2.显示实例化
    • 3.其它问题
  • 六、类模板
    • 1.类模板与模板类
    • 2.类模板的实例化
  • 七、总结

一、模板简介

模板是一个非常强大的C++功能,STL的各种组件也是基于模板的。所以,有必要了解一下C++的模板。

有了模板,就可以针对广泛的类型去写代码
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段,模板时泛型编程的基础

模板的参数又叫做虚拟类型参数
<>里面的参数又叫做模板实参表

二、模板的声明和定义

1.模板的声明

template<typename T>  int compare (T t1, T t2);
template<typename T>  class compare;
//也可以用typelate<class T>,现阶段五区别

2.函数模板的定义


template <typename T>
int compare(T & t1, T & t2)
{
    return t1>t2;
}

3.定义一个类模板

template <typename T>
class compare
{
public:
    
private:
    T _value;
};

三、模板工作原理

模板定义并不是真正定义了一个函数或者类,而是编译器通过程序员写出的模板和形参自动生成对应版本的定义,这个过程就叫做模板的推演和实例化,编译器生成的版本通常被称作模板的实例,编译器生成的具体过程,类似于宏替换
由于编译器不回去调用模板本身,所以一般模板是放在头文件中的

四、函数模板

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据是参类型产生函数的特定类型版本,但是该函数模板是不会被改变的

函数模板格式:

//处理用typename以外,还可以用class T1,classT2....
template<typename T1,typename T2.....>
//下面写一个函数

现阶段用typename和class都是一样,T是随便起的名字,一般用的大写首字母

template<typename T>
//template<class T>
void Swap(T&left,T&right)
{
	T tmp = left;
	left=right;
	right=tmp;
}
/*注意,泛型的Swap不能用异或来实现,因为异或
只针对整型,对于浮点数就不行了,对自定义类型更扯
*/
int main()
{
	int a=1,b=2;
	double x=1.1,y=2.2;
	//1.写模板
	Swap(a,b);
	Swap(x,y);
	//2.函数重载
}

对于不同的类型,会进行推演和实例化,因为需要生成特定的函数,不是使用的模板,所以需要实例化
在这里插入图片描述
因为有了模板,所以编译的时间也会相对长

不同的函数对应的地址也是不同的,上面的三个函数调用的是三个地址,也就说明了不是去调用的模板,而是另外生成了三个。

五、函数模板的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化,模板参数的实例化分为:隐式实例化和显示实例化

1.隐式实例化

让编译器根据实参推演模板参数的实际类型
模板的参数是不能隐式类型转换的,普通函数可以

template<typename T>
T Add(const T&left,const T&right)
{
	return left+right;
}
int main()
{
	Add(1.1,2);//报错
	return 0;
}

报错原因:
在传参的时候是可以隐式类型转换的,但是在推演实例化的时候就过不去了
解决方法:
a.在传参的时候强制类型转换去解决
b.显示实例化(下面)
c.多模板参数

2.显示实例化

指定实例化的类型

template<typename T>
void Swap(T&left,T&right)
{
	T tmp=left;
	left=right;
	right=tmp;
}
int main()
{
	int a=10,b=20;
	Swap<int>(a,b);
	return 0;
}

像刚才说的哪种,必须要显示实例化才行,如下

template<typename T>
T Add(const T&left,const T&right)
{
	return left+right;
}
int main()
{
	int a=10,b=20;
	double x=1.1,y=2.2;
	int sum = Add<int>(a+x);
	double res = Add<double>(a+x);
	return 0;
}

想要在模板推演实例化的时候进行类型转换,就需要显示实例化去执行实例化的类型。不然的话推演实例化过程中是不会发生隐式类型转换的,编译器报错。

3.其它问题

首先是可以存在多个模板参数的

template<typename T1,typename T2>
T1 Add(const T1& left,const T2& right)
{
	return left+right;
}

函数模板和普通的函数可以同时存在,有现成的就直接用

template<typename T>
T Add(const T&left,const T&right)
{
	return left+right;
}

int Add(int left,int right)//这个本来就是拷贝,不需要const
{
	return left+right;
}

六、类模板

1.类模板与模板类

类模板是一个模板,是类的抽象
模板类是一个类,用类模板生成的类

2.类模板的实例化

类模板都是显示实例化

template<class T>
//template<typename T>
class Stack
{	
public:
	Stack(size_t capacity=4)
		:_a(nullptr)
		,top(0)
		,capacity(0)
	{
		_a= new T[capacity];
		_capacity = capacity;
		_top=0;
	}
private:
	T* _a;
	int _top;
	int _capacity;
};
int main()
{
	Stack<int> st1;
	Stack<char> st2;
	Stack<double> st3(100);
	return 0;
}

另外,模板是不支持分离编译的,有支持的方法,但非常麻烦,后面再说,也就是说模板并不能够声明放在.h,定义放在.cpp,原因后面再说,只支持放在一个文件里。其次,模板也是可以给缺省值的,不过这个缺省值是类型,template<typename T = int>,不过就算是有了缺省值,实例化 的时候<>还是要加上。

七、总结

上面对C++类和对象剩下重要知识点进行了总结,感谢大家的支持,类和对象的内容就更新完了,后面我会继续更新内存管理有关方面的内容!
在这里插入图片描述

相关文章:

  • 微服务项目:尚融宝(14)(前端平台:尚融宝管理系统路由配置)
  • 中国电子用柔性阻隔膜行业产销需求与应用规模预测报告2022-2028年
  • C/C++面经嵌入式面经软件开发面经<26/30>-- 操作系统(五)
  • C/C++面经嵌入式面经软件开发面经<28/30>-- 单片机相关(一)
  • [iOS]-NSTimer与循环引用的理解
  • SpringCloudAlibaba2.2.6.RELEASE集成Gateway并实现JWT鉴权
  • Alevel经济知识点讲解:effects of deflation
  • 安装Docker后的一些配置
  • 智能驾驶功能软件平台设计规范第三部分:预测功能服务接口
  • 网课搜题公众号在线制作
  • Linux性能优化思路和方法
  • 什么是数据仓库?
  • 01|一条SQL查询语句是如何查询的?
  • NLP基础
  • 公众号查题系统平台
  • Angular2开发踩坑系列-生产环境编译
  • Java教程_软件开发基础
  • JS题目及答案整理
  • magento 货币换算
  • Spark RDD学习: aggregate函数
  • Vue官网教程学习过程中值得记录的一些事情
  • 闭包--闭包之tab栏切换(四)
  • 初识MongoDB分片
  • 创建一个Struts2项目maven 方式
  • 开源SQL-on-Hadoop系统一览
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 前端_面试
  • 三栏布局总结
  • 一个完整Java Web项目背后的密码
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​业务双活的数据切换思路设计(下)
  • #if 1...#endif
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (06)Hive——正则表达式
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (TOJ2804)Even? Odd?
  • (zhuan) 一些RL的文献(及笔记)
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (搬运以学习)flask 上下文的实现
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (二十三)Flask之高频面试点
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (南京观海微电子)——COF介绍
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (转)程序员技术练级攻略
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .Net CoreRabbitMQ消息存储可靠机制
  • .NET Core中的去虚
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .NET中的十进制浮点类型,徐汇区网站设计