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

C++初阶——模板初阶

目录

1、如何实现一个通用的交换函数

2、函数模板

2.1 函数模板的概念

2.2 函数模板的格式

2.3 函数模板的原理

2.4 函数模板的实例化

2.5 模板参数的匹配原则

3、类模板

3.1 类模板的格式

3.2 类模板的实例化


1、如何实现一个通用的交换函数

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

使用函数重载虽然可以实现,但是:

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

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

那能否告诉编译器一个模板,让编译器根据不同的类型利用该模板来生成代码呢

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

2、函数模板

2.1 函数模板的概念

函数模板代表了一个函数家族,该函数模板与类型无关在使用时被参数化,根据实参类型生成具体的函数

2.2 函数模板的格式

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

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

template<typename T>
void Swap(T& left, T& right)
{T temp = left;left = right;right = temp;
}

注意:typename是用来定义模板参数的关键字,也可以使用class(切记:不能使用struct代替 class)

2.3 函数模板的原理

函数模板是一个蓝图,它本身并不是函数是编译器用使用方式产生特定具体类型函数的模具。 所以其实模板就是将本来应该我们做的重复的事情交给了编译器。

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

2.4 函数模板的实例化

不同类型的参数使用函数模板时,称为函数模板的实例化

模板实例化分为:

1、隐式实例化编译器根据实参推演模板参数的实际类型

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

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);// 显式实例化Add<int>(a1, d1);return 0;
}

2.5 模板参数的匹配原则

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

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(1, 2.0); // 函数模板可以生成更好匹配的版本,编译器根据实参生成更好匹配的Add函数
}

3. 模板函数不允许自动类型转换,但普通函数可以自动类型转换

3、类模板

类模板概念、原理、匹配原则与函数模板类似

3.1 类模板的格式

template<class T1, class T2, ..., class Tn>
class 类模板名
{// 类内成员定义
};
#include<iostream>
using namespace std;// 类模版
template<typename T>
class Stack
{
public:Stack(size_t capacity = 4):_aaray(new new T[capacity]),_capacity(capacity),_size(0){}void Push(const T& data);private:T* _array;size_t _capacity;size_t _size;
};// 类模版的成员函数,不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误
// 在同一个文件中声明和定义分离,
// 要在函数上方再写个模板参数template<class T>,和指定类域Stack<T>::
template<class T>
void Stack<T>::Push(const T& data)
{// 扩容_array[_size] = data;++_size;
}int main()
{Stack<int> st1;    // intStack<double> st2; // doublereturn 0;
}

3.2 类模板的实例化

类模板只能显示实例化,在类名后的<>中指定模板参数的实际类型 。

注意:

1、好像typedef也可以达到类模板的效果,但是,

类模板可以同时实例化出不同类型的类,而typedef只能存在一个,如:

// 类模版
template<typename T>
class Stack
{
public:Stack(size_t capacity = 4):_aaray(new new T[capacity]),_capacity(capacity),_size(0){}void Push(const T& data);private:T* _array;size_t _capacity;size_t _size;
};int main()
{// 类模板都是显示实例化Stack<int> st1; // intst1.Push(1);st1.Push(2);st1.Push(3);Stack<double> st2; // doublest2.Push(1.1);st2.Push(1.1);st2.Push(1.1);// 同时有int、double类型的两个栈,而typedef就达不到这样的效果return 0;
}

2、为什么模板的形参类型,好像都是const T& x,因为,

T&是内置类型无所谓,若是自定义类型,可以减少拷贝

对于const取决于需不需要改变x

3、类模板的参数必须是虚拟类型(即非类型参数)吗?不是,

C++中类模板的参数即为模板参数列表中内容,有两种方式:

类型参数:即类型参数化,将来实例化为具体的实际类型,有点像函数的形参,形参可以接受不同值的实参。

非类型参数:在定义时给定了具体的类型用该类型定义的为常量,比如:

    template<class T, size_t N>class array{// ...};

4、类模板中的成员函数全是函数模板?

所以成员函数放在类外定义时,需要加模板参数列表,和在函数名前加类名::,而类名实际为ClassName<T>

相关文章:

C++初阶——模板初阶

目录 1、如何实现一个通用的交换函数 2、函数模板 2.1 函数模板的概念 2.2 函数模板的格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 3、类模板 3.1 类模板的格式 3.2 类模板的实例化 1、如何实现一个通用的交换函数 void Swap(int& lef…...

y3编辑器文档3:物体编辑器

文章目录 一、物体编辑器简介1.1 界面介绍1.2 复用(导入导出)1.3 收藏夹(项目资源管理)1.4 对象池二、单位2.1 数据设置2.2 表现设置2.3 单位势力和掉率设置2.4 技能添加和技能参数修改2.5 商店2.5.1 商店属性设置2.5.2 商店物品设置三、装饰物3.1 属性编辑3.2 碰撞体积四、…...

Linux-USB驱动实验

USB 是很常用的接口&#xff0c;目前大多数的设备都是 USB 接口的&#xff0c;比如鼠标、键盘、USB 摄像头等&#xff0c;我们在实际开发中也常常遇到 USB 接口的设备&#xff0c;本章我们就来学习一下如何使能 Linux内核自带的 USB 驱动。注意&#xff01;本章并不讲解具体的 …...

【配置查询】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…...

JavaWeb学习--cookie和session

目录 &#xff08;一&#xff09;Cookie概述 1.什么叫Cookie 2.Cookie规范 3.Cookie的覆盖 4.cookie的最大存活时间 ​​​​​​&#xff08;Cookie的生命&#xff09; &#xff08;二&#xff09; Cookie的API 1.创建Cookie&#xff1a;new 构造方法 2.保存到客户端浏…...

Next.js系统性教学:动态路由与并行路由

更多有关Next.js教程&#xff0c;请查阅&#xff1a; 【目录】Next.js 独立开发系列教程-CSDN博客 目录 1. 动态路由 (Dynamic Routes) 1.1 动态路由的基础 1.2 获取动态参数 1.3 动态嵌套路由 1.4 捕获所有动态路由 2. 并行路由 (Parallel Routes) 2.1 并行路由的基础…...

Backblaze 2024 Q3硬盘故障质量报告解读

作为一家在2021年在美国纳斯达克上市的云端备份公司&#xff0c;Backblaze一直保持着对外定期发布HDD和SSD的故障率稳定性质量报告&#xff0c;给大家提供了一份真实应用场景下的稳定性分析参考数据&#xff1a; 以往报告解读系列参考&#xff1a; Backblaze发布2024 Q2硬盘故障…...

[创业之路-179]:《领先的密码 - BLM核心方法体系与企业实践》主要章节与主要内容

目录 前言&#xff1a; 1、引言或概述 2、BLM方法论的背景与起源 3、BLM方法论的发展与完善 4、BLM方法论的重要性与价值 5、本书的内容与结构 二、BLM核心方法体系 1. 领先的起点 2. 领先的战略 3. 领先的执行 4. 领先之魂 三、本书的核心思想 1、以战略为核心 …...

uniapp的生命周期

在 UniApp 中&#xff0c;生命周期函数是指在组件&#xff08;如页面、视图等&#xff09;创建和销毁过程中会自动触发的一些函数。UniApp 提供了多种生命周期函数&#xff0c;帮助开发者在适当的时机进行相关的逻辑处理。 UniApp 的生命周期函数可以分为 页面生命周期 和 组件…...

基于 RNN(GRU, LSTM)+CNN 的红点位置检测(pytorch)

文章目录 1 项目背景2 数据集3 思路4 实验结果5 代码 1 项目背景 需要在图片精确识别三跟红线所在的位置&#xff0c;并输出这三个像素的位置。 其中&#xff0c;每跟红线占据不止一个像素&#xff0c;并且像素颜色也并不是饱和度和亮度极高的红黑配色&#xff0c;每个红线放大…...

L2G3000-LMDeploy 量化部署实践

文章目录 LMDeploy 量化部署实践闯关任务环境配置W4A16 量化 KV cacheKV cache 量化Function call LMDeploy 量化部署实践闯关任务 环境配置 conda create -n lmdeploy python3.10 -y conda activate lmdeploy conda install pytorch2.1.2 torchvision0.16.2 torchaudio2.1.…...

verilog编程规范

verilog编程规范 文章目录 verilog编程规范前言一、代码划分二、verilog编码ABCDEFG 前言 高内聚&#xff0c;低耦合&#xff0c;干净清爽的代码 一、代码划分 高内聚&#xff1a; 一个功能一个模块干净的接口提取公共的代码 低耦合&#xff1a; 模块之间低耦合尽量用少量…...

飞飞5.4游戏源码(客户端+服务端+工具完整源代码+5.3fix+5.4patch+数据库可编译进游戏)

飞飞5.4游戏源码&#xff08;客户端服务端工具完整源代码5.3fix5.4patch数据库可编译进游戏&#xff09; 下载地址&#xff1a; 通过网盘分享的文件&#xff1a;【源码】飞飞5.4游戏源码&#xff08;客户端服务端工具完整源代码5.3fix5.4patch数据库可编译进游戏&#xff09; 链…...

【MySQL】——​​用一文领悟表的增删查改

目录 前言 &#x1f343;1.表的增加 &#x1f359;1.1增——insert &#x1f359;1.2插入否则更新 &#x1f364;1.2.1影响行说明 &#x1f342;2.表的查询 &#x1f358;2.1查询——select &#x1f358;2.2特殊表查询 &#x1f365;2.2.1添加表达式 &#x1f365;…...

Zabbix监控Oracle 19c数据库完整配置指南

Zabbix监控Oracle 19c数据库完整配置指南 本文将详细介绍如何使用Zabbix配置Oracle 19c数据库监控&#xff0c;包括安装、配置、问题排查等全过程。本指南适合新手独立完成配置。 1. 环境准备 1.1 系统要求 Oracle 19c数据库服务器Zabbix服务器&#xff08;版本5.0或更高&a…...

静态路由与交换机配置实验

1.建立网络拓扑 添加2台计算机&#xff0c;标签名为PC0、PC1&#xff1b;添加2台二层交换机2960&#xff0c;标签名为S0、S1&#xff1b;添加2台路由器2811&#xff0c;标签名为R0、R1&#xff1b;交换机划分的VLAN及端口根据如下拓扑图&#xff0c;使用直通线、DCE串口线连接…...

【jvm】讲讲jvm中的gc

目录 1. 说明2. 主要算法2.1 标记-清除算法2.2 复制算法2.3 标记-整理算法3. 主要回收器3.1 Serial GC3.2 Parallel GC3.3 CMS&#xff08;Concurrent Mark-Sweep&#xff09;GC3.4 G1&#xff08;Garbage-First&#xff09;GC 4. 触发条件4.1 Minor GC&#xff08;Young GC&am…...

openlayers地图事件

OpenLayers是一个开源的JavaScript库&#xff0c;用于在Web上创建交互式地图。它提供了许多地图事件&#xff0c;使用户可以与地图进行交互。以下是OpenLayers常用的地图事件&#xff1a; 1. click&#xff1a;当用户单击地图时触发该事件。 2. dblclick&#xff1a;当用户双…...

杂记9---一些场景git操作汇总

背景&#xff1a;不同项目需求&#xff0c;所需要git操作集合&#xff0c;不太一样&#xff0c;这里汇总记录一下。 场景1&#xff1a;给本地项目添加到远程仓库的新建分支上 把本地节点保存在自己库的一个分支&#xff1a; git init git remote add origin xxx.git 远程仓库…...

Mysql索引,聚簇索引,非聚簇索引,回表查询

什么是索引 数据库索引是为了实现高效数据查询的一种有序的数据数据结构&#xff0c;类似于书的目录&#xff0c;通过目录可以快速的定位到想要的数据&#xff0c;因为一张表中的数据会有很多&#xff0c;如果直接去表中检索数据效率会很低&#xff0c;所以需要为表中的数据建立…...

Phi-4-mini-reasoning作品集:自动将推理过程转化为教学级讲解语言

Phi-4-mini-reasoning作品集&#xff1a;自动将推理过程转化为教学级讲解语言 1. 模型简介 Phi-4-mini-reasoning是一个轻量级的开源文本生成模型&#xff0c;专注于将复杂推理过程转化为清晰易懂的教学语言。作为Phi-4模型家族的一员&#xff0c;它特别擅长处理需要逐步解释…...

n8n-nodes-puppeteer自动化解决方案:三步掌握无代码浏览器控制技术

n8n-nodes-puppeteer自动化解决方案&#xff1a;三步掌握无代码浏览器控制技术 【免费下载链接】n8n-nodes-puppeteer n8n node for requesting webpages using Puppeteer 项目地址: https://gitcode.com/gh_mirrors/n8/n8n-nodes-puppeteer 在数字化时代&#xff0c;如…...

C++实战:高精度阶乘算法的实现与优化

1. 为什么我们需要高精度阶乘算法&#xff1f; 当你第一次学习编程时&#xff0c;可能会用循环或递归来实现阶乘计算。比如用C写个简单的for循环&#xff0c;轻松计算出5! 120。但当你尝试计算20!时&#xff0c;事情就开始变得有趣了——你会发现结果完全不对&#xff0c;甚至…...

【喜报】义翘神州再获CNAS认可,全面对标2025版药典新标准

义翘神州生物安全检测实验室近日成功通过中国合格评定国家认可委员会&#xff08;CNAS&#xff09;的扩项评审及定期监督评审&#xff0c;并已完成全部能力附表更新&#xff01;这标志着实验室技术能力与质量管理体系持续符合ISO/IEC 17025:2017国际标准的严苛要求&#xff0c;…...

Qwen3.5-4B模型在嵌入式系统日志智能分析中的实践

Qwen3.5-4B模型在嵌入式系统日志智能分析中的实践 1. 嵌入式日志分析的痛点与机遇 在物联网网关、工业控制器等嵌入式设备运行过程中&#xff0c;系统日志就像设备的"健康日记"&#xff0c;记录着每一次心跳、每一次异常。传统运维人员需要像"破译密码"一…...

RSA2 - Writeup by AI

RSA2 - Writeup by AI 题目信息项目内容题目来源Bugku CTF题目类型Crypto (密码学)考点RSA 小指数攻击、Rabin 加密题目描述 给定 RSA 加密参数&#xff1a; 加密指数 e 2模数 N&#xff08;3072 位&#xff09;密文 c 要求解密得到 flag。 考点分析 核心知识点 RSA 小指数攻击…...

OpenCV实战:图像亮度、对比度与锐化的智能调节与优化

1. 图像处理基础概念解析 在开始动手实践之前&#xff0c;我们需要先理解几个关键概念。亮度、对比度和锐化这三个参数就像调节电视画面的三个旋钮&#xff0c;每个旋钮都会对图像产生独特的影响。 亮度&#xff08;Brightness&#xff09;就像房间里的灯光开关。调高亮度&…...

Hunyuan-MT-7B翻译终端效果展示:Pixel Language Portal长文本段落对齐精度对比

Hunyuan-MT-7B翻译终端效果展示&#xff1a;Pixel Language Portal长文本段落对齐精度对比 1. 产品概览&#xff1a;像素语言冒险工坊 **像素语言跨维传送门(Pixel Language Portal)**是一款基于腾讯Hunyuan-MT-7B核心引擎构建的创新翻译终端。与传统翻译工具不同&#xff0c…...

4个硬核特性解决开发者存储管理难题

4个硬核特性解决开发者存储管理难题 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka 一、存储困境诊断&#xff1a;开发者面临的四大存储挑战 识别…...

智能处理与开源工具:突破传统背景抠图限制的实时解决方案

智能处理与开源工具&#xff1a;突破传统背景抠图限制的实时解决方案 【免费下载链接】obs-backgroundremoval An OBS plugin for removing background in portrait images (video), making it easy to replace the background when recording or streaming. 项目地址: https…...