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

C++ 模板

1. 泛型编程

实现一个通用的交换函数,使用函数重载虽然可以实现,但是有以 下几个不好的地方:

1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函

2. 代码的可维护性比较低,一个出错可能所有的重载均出错

因此,我们可以给编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。泛型编程代码可以处理不同类型,不同结构的数据

模板是泛型编程的基础,但模板不等于泛型编程。

2. 函数模板

2.1 函数模板概念

函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

方法要通用,在实现时类型就不能具体化--类型给具体了方法只能处理该种类型其他处理不了

2.1 函数模板格式

template<typename T1, typename T2,......,typename Tn>

返回值类型 函数名(参数列表){}

举例加法模板

#include<iostream>
using namespace std;//方法要通用,在实现时类型就不能具体化--类型给具体了方法只能处理该种类型其他处理不了
//要告诉编译器,T是一个类型
//typedef double T; 这种方式错误,实际上还是double类型//定义一个ADD模板
template<typename T>
T Add(const T& left, const T& right) 
{cout << typeid(T).name() << endl;return left + right;
}int main()
{Add(10, 20);Add(10.2, 2.0);return 0;
}

注意:typename是用来定义模板参数关键字也可以使用class(但是一般不用,class定义类,不要引起歧义)

(不能使用struct代替class) 这也是二者区别之一

2.3 函数模板的原理

函数模板不是一个函数,是一个规则

  1. 在实例化之前:只是对模板进行简单的语法检测

  1. 在实例化之后:根据用户对函数模板的实例化结果来生成处理对应类型的代码,并对这些代码进行再次编译

在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此

ADD(1,2) //都为Int,认为T为int类型,则会根据模板生成处理int类型的ADD<int>函数
ADD(2.1,4.2) //都为double,认为T为double类型,则会根据模板生成处理double类型的ADD<double>函数
ADD('1','2') //都为char,认为T为char类型,则会根据模板生成处理int类型的ADD<char>函数ADD(1,2.2) //T到底设置为int,还是double类型,编译器无法确定,解决方法如下

1.强转

ADD(1,(int)2.2)

2.增加模板

template<typename T, typename S>
  1. 对模板进行显式实例化,明确指明模板参数列表中T的实际类型

ADD<double>(1,2.2);

2.4 函数模板的实例化

显式实例化:在函数名后的<>中指定模板参数的实际类型

显式实例化:明确指定了参数类表中T的实际类型,不需要推演T的类型,如上代码举例

如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错

隐式实例化:没有明确指出参数类表中T的实际类型,编译器需要推演用户传递的类型来确定模板参数列表T的类型,如2.1中代码例子

3. 类模板

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;
}

3.2 类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>

中即可,类模板名字不是真正的类,而实例化的结果才是真正的类

// Vector类名,Vector<int>才是类型
Vector<int> s1;
Vector<double> s2;

相关文章:

C++ 模板

1. 泛型编程实现一个通用的交换函数&#xff0c;使用函数重载虽然可以实现&#xff0c;但是有以 下几个不好的地方&#xff1a;1. 重载的函数仅仅是类型不同&#xff0c;代码复用率比较低&#xff0c;只要有新类型出现时&#xff0c;就需要用户自己增加对应的函数2. 代码的可维…...

C++中的友元及运算符重载

友元 意义 程序中&#xff0c;有些私有属性也想让类外特殊的一些函数或者类进行访问&#xff0c;就要用到友元技术 关键字 friend 友元的三种实现 全局函数做友元 class Room{friend void test(Person &p);//friend class test;public:string phone_number;private:string…...

五、运行时数据区内部结构、JVM中的线程

内存是非常重要的系统资源&#xff0c;是硬盘和cpu的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时运行。JVM内存布局规定了Java在运行过程种内存申请、分配‘、管理的策略&#xff0c;保证了JVM的高效稳定运行&#xff0c;不同的JVM对于内存的划分方式和管理机制…...

Codeforces Round #848 (Div. 2)A-C

传送门 目录 A. Flip Flop Sum 代码&#xff1a; B. The Forbidden Permutation 代码&#xff1a; C. Flexible String 代码&#xff1a; A. Flip Flop Sum 题意&#xff1a;给你一个长度为n的数组&#xff08;数组元素只为1或者-1&#xff09;&#xff0c;你要且只能进行…...

机器学习笔记之近似推断(一)从深度学习角度认识推断

机器学习笔记之近似推断——从深度学习角度认识推断引言推断——基本介绍精确推断难的原因虽然能够表示&#xff0c;但计算代价太大无法直接表示引言 本节是一篇关于推断总结的博客&#xff0c;侧重点在于深度学习模型中的推断任务。 推断——基本介绍 推断(Inference\text{…...

指针的进阶

一、字符指针 int main() {char ch w;char* pc &ch;//pc就是字符指针//const char *p "abcdef";//这里其实是把字符串"abcdef"的首地址放入了指针p中//*p w;//这是错误的无法修改值&#xff08;可以看到这里绿色波浪线警告&#xff09;char arr[] …...

一元二次方程方程的类

1 问题设计一个一元二次方程的类&#xff0c;其中包括能够反映一元二次方程的属性与操作行为&#xff0c;然后再设计一个测试类&#xff0c;检测类的使用情况。2 方法使用package语句将方程的属性即计算跟的方法封装在一个有包名的类中&#xff0c;包名为tom.jiafei&#xff0c…...

Ask林曦|来回答,30个你关心的日常问题(二)

在林曦老师的线上书法直播课上&#xff0c;上课前后的聊天时间里&#xff0c;时常有同学向林曦老师提问&#xff0c;这些问题涵盖了日常生活的诸多方面&#xff0c;从身体的保养&#xff0c;到快乐的法门&#xff0c;皆是大家感兴趣的&#xff0c;也都共同关切的。   暄桐教室…...

哪款电容笔适合开学季?电容笔和Apple Pencil的区别

其实&#xff0c;市场上一般的电容笔和Apple Pencil的最大差别&#xff0c;就在于Apple Pencil与普通电容笔两者的重量和压感。然而&#xff0c;由于苹果电容笔价格过高&#xff0c;目前电容笔的市场份额逐渐转向平替电容笔&#xff0c;平替电容笔其性能也逐渐得到改善。下面&a…...

Qt之Qprocess

QProcess 可用于完成启动外部程序&#xff0c;并与之交互通信。 一、启动外部程序的两种方式   1&#xff09;一体式&#xff1a;void QProcess::start(const QString & program,const QStringList &arguments,OpenMode mode ReadWrite)     外部程序启动后&…...

为什么不愿意专升本 学历有什么用

专升本包括两种形式普通专升本和成人专升本。普通专升本毕业是全日制学历&#xff0c;考试仅有一次&#xff0c;错过不能补考所以考生不愿意选择&#xff0c;成人专升本毕业是非全日制学历&#xff0c;学历被国家承认&#xff0c;和普通高校毕业证有相同的使用效力。为何考生不…...

构造函数的使用大全

概述 在C中创建一个对象时&#xff0c;通常需要做一些数据初始化的工作&#xff0c;因此便提供了一个特殊的成员函数 —— 构造函数。一般情况下&#xff0c;并不需要程序员主动调用构造函数&#xff0c;而是在创建对象时&#xff0c;由系统自动调用。构造函数可以由程序员定义…...

ASP.NET Core MVC 项目 IOC容器

目录 一&#xff1a;什么是IOC容器 二&#xff1a;简单理解内置Ioc容器 三&#xff1a;依赖注入内置Ioc容器 四&#xff1a;生命周期 五&#xff1a;多种注册方式 一&#xff1a;什么是IOC容器 IOC容器是Inversion Of Control的缩写&#xff0c;翻译的意思就是控制反转。 …...

ARM工控机/网关- 钡铼技术

一、NXP处理器ARM控制器的介绍 NXP半导体是汽车、穿戴、消费电子等领域中智能机器解决方案的领先供应商。其产品线庞大&#xff0c;包括处理器、微控制器、快速设计平台、ARM控制器等。在物联网控制、汽车电子、安全应用等领域&#xff0c;NXP处理器ARM控制器已成为半导体行业的…...

为什么都在喊数据可视化?它究竟怎么做?

在数字化转型的浪潮中&#xff0c;不论是传统行业&#xff0c;还是新兴行业总会提到“数据可视化”这个词。那数据可视化到底是什么&#xff1f;为什么会受到那么多人追捧&#xff1f;又该怎么才能做到数据可视化呢&#xff1f; 一、数据可视化是什么&#xff1f; 首先“可视…...

nodejs+vue停车场停车位短租系统vscode

目 录前端技术&#xff1a;nodejsvueelementui 前端&#xff1a;HTML5,CSS3、JavaScript、VUE 1、 node_modules文件夹(有npn install产生) 这文件夹就是在创建完项目后&#xff0c;cd到项目目录执行npm install后生成的文件夹&#xff0c;下载了项目需要的依赖项。 2、…...

物理真机上LUKS结合TPM的测试 —— 使用随机数密钥

1. 创建磁盘空间 命令如下&#xff1a; dd if/dev/zero ofenc.disk bs1M count50 实际命令及结果如下&#xff1a; $ dd if/dev/zero ofenc.disk bs1M count50 输入了 500 块记录 输出了 500 块记录 52428800 字节 (52 MB, 50 MiB) 已复制&#xff0c;0.0587495 s&#xff…...

Linux USB 开发指南

文章目录Linux USB 开发指南1 前言1.1 文档简介1.2 目标读者1.3 适用范围2 模块介绍2.1 模块功能介绍2.2 相关术语介绍2.3 模块配置介绍2.3.1 Device Tree 配置说明2.3.2 board.dts 配置说明2.3.3 kernel menuconfig 配置说明2.4 源码结构介绍2.5 驱动框架介绍2.6 Gadget 配置2…...

FreeRTOS入门(03):队列、信号量、互斥量

文章目录目的队列&#xff08;queue&#xff09;信号量&#xff08;semaphore&#xff09;互斥量&#xff08;mutex&#xff09;互斥量递归互斥量总结目的 FreeRTOS提供给用户最核心的功能是任务&#xff08;Task&#xff09;&#xff0c;实际项目中通常会有多个任务&#xff…...

Biome-BGC在模拟过程中,如何使用Linux、Python等,完成前处理和后处理工作???

在Biome-BGC模型中&#xff0c;对于碳的生物量积累&#xff0c;采用光合酶促反应机理模型计算出每天的初级生产力(GPP)&#xff0c;将生长呼吸和维持呼吸减去后的产物分配给叶、枝条、干和根。生物体的碳每天都按一定比例以凋落方式进入凋落物碳库&#xff1b;对于水份输运过程…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...