模板(上)

news2024/11/16 9:48:33


文章目录

  • 泛型编程
  • 函数模板
  • 类模板

一、泛型编程

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础

void Swap(int& left, int& right)
{
	int temp = left;
	left = right;
	right = temp;
}
void Swap(double& left, double& right)
{
	double temp = left;
	left = right;
	right = temp;
}
void Swap(char& left, char& right)
{
	char temp = left;
	left = right;
	right = temp;
}

观察上述三个Swap函数可以发现:对于传入Swap的类型来写出其相应的函数,这样使得代码的复用性比较差,所以我们可以通过设计一个模板的思想,让编译器推导出其对应的参数类型。

 


二、函数模板

1.函数模板概念

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

 

函数模板格式
template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表){}
template<typename T>
void Swap(T& left, T& right)
{
	T temp = left;
	left = right;
	right = temp;
}

2.函数模板的原理

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。

3.函数模板的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化
1. 隐式实例化:让编译器根据实参推演模板参数的实际类型
template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}
int main()
{
	int a1 = 10, a2 = 20;
	double d1 = 10.0, d2 = 20.0;
	Add(a1, a2);
	Add(d1, d2);

	/*
	该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型
	通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T,
	编译器无法确定此处到底该将T确定为int 或者 double类型而报错
	注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅
	Add(a1, d1);
	*/

	// 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化
	Add(a1, (int)d1);
	return 0;
}

2. 显式实例化:在函数名后的<>中指定模板参数的实际类型
template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}
int main(void)
{
	int a = 10;
	double b = 20.0;

	// 显式实例化
	Add<int>(a, b);
	return 0;
}

3.模板参数的匹配原则

1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数
// 专门处理int的加法函数
int Add(int left, int right)
{
	return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right)
{
	return left + right;
}
void Test()
{
	Add(1, 2); // 与非模板函数匹配,编译器不需要特化
	Add<int>(1, 2); // 调用编译器特化的Add版本
}

2.对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板

// 专门处理int的加法函数
int Add(int left, int right)
{
	return left + right;
}
// 通用加法函数
template<class T1,class T2>
T1 Add(T1 left, T2 right)
{
	return left + right;
}
void Test()
{
	Add(1, 2); // 与非模板函数匹配,编译器不需要特化
	Add<int>(1, 2.0); // 调用编译器特化的Add版本
}
3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

三、类模板

1 类模板的定义格式

 
template < class T1 , class T2 , ..., class Tn >
class 类模板名
{
// 类内成员定义
};
// 注意:Vector不是具体的类,是编译器根据被实例化的类型生成具体类的模具
template<class T>
class Vector
{
public:
	Vector(size_t capacity = 10)
		: _pData(new T[capacity])
		, _size(0)
		, _capacity(capacity)
	{}

	// 使用析构函数演示:在类中声明,在类外定义。
	~Vector();

	void PushBack(const T& data);
		void PopBack();
		// ...

		size_t Size() { return _size; }

	T& operator[](size_t pos) {
		assert(pos < _size);
		return _pData[pos];
	}

private:
	T* _pData;
	size_t _size;
	size_t _capacity;
};
// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{
	if (_pData)
		delete[] _pData;
	_size = _capacity = 0;
}

注意:模板不支持在将声明写到.h文件中,定义写作.cpp源文件中这种声明和定义不在同一个文件中会导致链接发生错误,如果将声明和定义写入在.h文件中此时该文件后缀名可为.hpp。

2 类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<> 中即可,类模板名字不是真正的类,而实例化的结果才是真正的类

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/728839.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是混合云?

混合云&#xff08;Hybrid Cloud&#xff09;是指结合了私有云和公有云的计算环境。私有云是指在企业内部建立的基础设施&#xff0c;由企业自己管理和控制&#xff1b;而公有云是由第三方云服务提供商&#xff08;如亚马逊AWS、微软Azure、谷歌云等&#xff09;提供的计算资源…

浅谈无效化一个空窗口的后果

有时候&#xff0c;你可能会注意到这样一个现象&#xff1a;桌面上的所有窗口都刷新了自身并产生了闪烁。 导致这个现象的原因之一是一个所谓的空句柄窗口 Bug。 如果你研究过 Win32 SDK 编程&#xff0c;则你应该比较熟悉这个函数&#xff1a;InvalidateRect。 调用这个函数可…

C# PaddleInference 图片旋转角度检测

效果 项目 VS2022.net4.8 OpenCvSharp4Sdcb.PaddleInference 代码 using OpenCvSharp; using Sdcb.PaddleInference; using Sdcb.PaddleInference.Native; using System; using System.Drawing; using System.Globalization; using System.Linq; using System.Runtime.Interop…

14天学会:基于J2EE的JAVA WEB基础

系列文章 手把手教你&#xff1a;基于Django的新闻文本分类可视化系统&#xff08;文本分类由bert实现&#xff09; 手把手教你&#xff1a;基于python的文本分类&#xff08;sklearn-决策树和随机森林实现&#xff09; 手把手教你&#xff1a;岩石样本智能识别系统 一、学习…

港联证券|股票长线投资技巧?

股票长线出资主要是看股票长时间的开展&#xff0c;所以主张从以下几个方面来剖析&#xff1a; 1、经济环境 把握宏观经济大势。股市是宏观经济的风向标&#xff0c;它在宏观经济的大环境中开展&#xff0c;而且经济的变动趋势也会影响长时间出资的收益。假如出资者能够把握住…

【java】修改JsonObject中的属性值

Java修改JsonObject中的属性值 <!-- 阿里JSON解析器 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.16</version></dependency>例子 public static void m…

设计师都在找的在线SVG编辑工具!赶快收藏

为了方便设计师编辑和修改SVG图形&#xff0c;本文将介绍5款易于使用的在线SVG编辑工具&#xff0c;一起来看看吧&#xff01; 1、即时设计 即时设计是一款强大的在线SVG编辑工具&#xff0c;它可以支持路径编辑、形状编辑、填充和边框编辑、文本编辑等多种编辑需求&#xff…

人工智能套装 Ai Kit 横向测评

本文涉及到的产品 1 mechArm 270 2 mycobot 280 3 mypalletizer 260 4 AI kit 主题内容 今天的文章的主题主要介绍一下跟aikit 套件搭配的三款机械臂&#xff0c;它们之间分别有什么不一样的地方。 前言 假如说你有一台机械臂的话&#xff0c;你会用它来干什么呢&#…

【Django学习】(十一)APIView_请求与响应_GenericAPIView

继承DRF中APIView之后&#xff0c;那么当前视图就具备了认证、授权、限流等功能 继承DRF中APIView之后&#xff0c;每一个实例方法中的request为Request对象 Request类拓展了Django中的HttpRequest类&#xff0c;具备很多额外优秀的功能Request类与HttpRequest类中的所有功能兼…

2022年06月份青少年软件编程Scratch图形化等级考试试卷二级真题(含答案)

2022-06 Scratch真题二级 分数&#xff1a;100 题数&#xff1a;37 一、单选题(共25题&#xff0c;共50分) 1.角色初始位置如图所示&#xff0c;下面哪个选项能让角色移到舞台的左下角&#xff1f;&#xff08; &#xff09;(2分) A. B. C. D. 2.点击绿旗&#xff0c;执…

【面试题27】Redis中的connect和pconnect如何使用,有什么区别

文章目录 一、背景二、connect函数三、pconnect函数四、区别和使用场景五、总结 一、背景 本文已收录于PHP全栈系列专栏&#xff1a;PHP面试专区。 计划将全覆盖PHP开发领域所有的面试题&#xff0c;对标资深工程师/架构师序列&#xff0c;欢迎大家提前关注锁定。 Redis是一个开…

六、HAL_Timer的PWM功能

1、开发环境 (1)Keil MDK: V5.38.0.0 (2)STM32CubeMX: V6.8.1 (3)MCU: STM32F407XGT6 2、PWM简介 2.1、什么是PWM (1)PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用&#xff0c;方波的占空比被调制用来对一个具体模拟信号的电平进行编码。 (2)P…

Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling

感想&#xff1a;由于看不懂官方代码的原因&#xff0c;自己这方面耽误了一段时间&#xff0c;一方面&#xff0c;在AI与经济学之间犹豫了许久&#xff0c;另一方面&#xff0c;工作 了半年&#xff0c;也没发工资&#xff0c;没空找培训代码的课程&#xff0c;所以停止更新了三…

Nginx-代理服务器详解

本文已收录于专栏 《中间件合集》 目录 概念说明Nginx代理 提供服务总结提升 概念说明 Nginx Nginx是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。它具有很多非常优越的特性&#xff1a;在连接高并发的情况下&#xff0c;Nginx是Aoache服…

机器学习算法之决策树(decision tree)

1 决策树算法介绍 决策树(Decision Tree,又称为判定树)算法是机器学习中常见的一类算法&#xff0c;是一种以树结构形式表达的预测分析模型。决策树属于监督学习&#xff08;Supervised learning&#xff09;&#xff0c;根据处理数据类型的不同&#xff0c;决策树又为分类决策…

html 模板

模板王 - 10000免费网页模板&#xff0c;网站模板下载大全 (mobanwang.com)http://www.mobanwang.com/

C++ string中内置的字符串操作和标准库中常用字符处理函数

&#x1f4af; 博客内容&#xff1a;C读取一行内个数不定的整数的方式 &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准前端&#xff0c;专注基础和实战分享 &#xff0c;欢迎私信&#xff01; &#x1f496; 欢迎大家&…

Qt之QDialog 自定义标题栏

简述 Qt自带标题栏功能还是很强大的&#xff0c;但是确实不能百分百满足需求&#xff0c;除了丑以外还不能随意更改标题栏字体&#xff0c;也不能更改样式&#xff1b;所以为了满足自己的虚荣心让标题栏变得更加好用看好看&#xff0c;特地花时间做了以下测试&#xff1b; 支持…

SpringBoot通过获取请求参数或者Headers上的特殊标识实现i18n国际化

实现效果 我们大部分都是把i18n的标识放在Headers上面&#xff1b;而把标识放在参数上的话比较少&#xff0c;放参数上的话一般是在使用a标签下载某些文件不好配置请求头的时候才使用上 配置在Headers上面&#xff1a; 配置在params上面&#xff1a; 配置代码&#xff1a; /**…

Django_类视图(五)

目录 类视图优点 使用方法 定义类视图 添加类视图路由 类视图原理 类视图的二次封装 类视图二次封装代码如下 编写视图 配置路由 访问url结果 源码等资料获取方法 类视图优点 使用django的函数视图&#xff0c;如果要让同一个视图实现不同的请求方式实现不同的逻辑…