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

C++:模板初阶(泛型编程、函数模板、类模板)

文章目录

  • 1 泛型编程
  • 2 函数模板
    • 2.1 函数模板概念
    • 2.2 函数模板格式
    • 2.3 函数模板的原理
    • 2.4 函数模板的实例化
    • 2.5 模板参数的匹配原则
  • 3 类模板
    • 3.1 类模板的定义格式
    • 3.2 类模板的实例化


1 泛型编程

所谓泛型,也就是通用型的意思。

在以往编写代码时,我们常常会需要实现两个数的交换(Swap函数),在C语言中,由于没有函数重载的概念,如果想实现不同类型数据的交换,就需要编写不同名但本质功能相同的函数;在C++中,则可以通过函数重载,编写同名的数据交换函数,虽然相比之下,函数重载避免了要取不同函数名的麻烦,但对于不同类型数据的交换仍需要单独编写函数,而重载的函数仅仅是类型不同,功能都是相似的,这样代码的复用率比较低,只要有新类型操作的需要,就得由用户自己增加对应的函数,且代码的可维护性比较低,一个出错,可能所有的重载均出错。

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

在实际生产生活中,对于造型相同的产品,通常会使用模具等来进行生产。那是否也能提供给编译器一个模具,让编译器根据不同的类型利用该模具来生成代码呢?

基于此,C++中提出了泛型编程的概念:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。

其中,模板可以分为:

  • 函数模板
  • 类模板

2 函数模板

2.1 函数模板概念

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

2.2 函数模板格式

template<typename T1, typename T2, ..., typename Tn>template<class T1, class T2, ..., class Tn>
返回值类型 函数名(参数列表){}
注意:typename 是用来定义模板参数的关键字,也可以使用 class(但不能使用 struct 代替 class)

示例代码:

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

2.3 函数模板的原理

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

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


2.4 函数模板的实例化

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

  • 隐式实例化:让编译器根据实参推演模板函数的实例类型
    示例代码:
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;
}
  • 显式实例化:在函数名后的 <> 中指定模板参数的实际类型;如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功,编译器将会报错。
    示例代码:
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;
}

2.5 模板参数的匹配原则

  • 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数
// 专门处理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版本
}
  • 对于非模板函数和同名函数模板,如果其它条件都相同,在调用时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数,那么将选择模板
// 专门处理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.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++中模板初阶相关知识的一些学习记录总结,如有错误,希望大家帮忙指正,也欢迎大家给予建议和讨论,谢谢!

相关文章:

C++:模板初阶(泛型编程、函数模板、类模板)

文章目录1 泛型编程2 函数模板2.1 函数模板概念2.2 函数模板格式2.3 函数模板的原理2.4 函数模板的实例化2.5 模板参数的匹配原则3 类模板3.1 类模板的定义格式3.2 类模板的实例化1 泛型编程 所谓泛型&#xff0c;也就是通用型的意思。 在以往编写代码时&#xff0c;我们常常…...

把数组排成最小的数 AcWing(JAVA)

输入一个正整数数组&#xff0c;把数组里所有数字拼接起来排成一个数&#xff0c;打印能拼接出的所有数字中最小的一个。 例如输入数组 [3,32,321][3,32,321]&#xff0c;则打印出这 33 个数字能排成的最小数字 321323321323。 数据范围 数组长度 [0,500][0,500]。 样例&#x…...

4.3 PBR

1. 实验目的 熟悉PBR的应用场景掌握PBR的配置方法2. 实验拓扑 PBR实验拓扑如图4-8所示: 图4-8:PBR 3. 实验步骤 (1) IP地址的配置 R1的配置 <Huawei>system-view...

hmac — 加密消息签名和验证

hmac — 加密消息签名和验证 1.概述 它的全称叫做Hash-based Message Authentication Code: 哈希消息认证码&#xff0c;从名字中就可以看出来这个hmac基于哈希函数的&#xff0c;并且还得提供一个秘钥key&#xff0c;它的作用就是用来保证消息的完整性&#xff0c;不可篡改。…...

AWS攻略——使用ACL限制访问

文章目录确定出口IP修改ACL修改主网络ACL修改入站规则修改子网ACL创建子网ACL新增入站规则新增出站规则关联子网假如我们希望限制只有公司内部的IP可以SSH登录到EC2&#xff0c;则可以考虑使用ACL来实现。 我们延续使用《AWS攻略——创建VPC》的案例&#xff0c;在它的基础上做…...

【已解决】关于 luckysheet 设置纯文本,解决日期格式回显错误的办法

目录 一、现象 二、分析 三、思考过程 五、解决 六、参考链接 一、现象 在excel里面输入内容&#xff0c;如 2023-2-17 12:00 保存后&#xff0c;传回后端的数据被转化成了 数值类型&#xff0c;这显然是一种困扰。 如图所示 二、分析 查阅了文档和一些博客发现 Lucky…...

Jackson

first you need to add dependence: gradle: implementation com.fasterxml.jackson.core:jackson-databind:2.13.1 implementation com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.1原生Jackson的使用示例: /*** 原生Jackson的使用示例*/ public class Jacks…...

字节软件测试岗:惨不忍睹的三面,幸好做足了准备,月薪19k,已拿offer

我今年25岁&#xff0c;专业是电子信息工程本科&#xff0c;19年年末的时候去面试&#xff0c;统一投了测试的岗位&#xff0c;软件硬件都有&#xff0c;那时候面试的两家公司都是做培训的&#xff0c;当初没啥钱&#xff0c;他们以面试为谎言再推荐去培训这点让我特别难受。后…...

vue使用axios发送post请求携带json body参数,后端使用@RequestBody进行接收

前言 最近在做自己项目中&#xff0c;做一个非常简单的新增用户场景&#xff0c;但是使用原生axios发送post请求的时候&#xff0c;还是踩了不少坑的。 唉&#xff0c;说多了都是泪&#xff0c;小小一个新增业务&#xff0c;在自己前后端一起开发的时候&#xff0c;硬是搞了好…...

【python百炼成魔】python之列表详解

文章目录一. 列表的概念1.1 列表是什么&#xff1f;1.2 为什么要使用列表&#xff1f;1.3 列表的定义二. 列表的增删改查操作2.1 列表的读取2.2 列表的切片2.3 列表的查询操作2.3.1 not in ,in 表达式2.3.2 列表元素遍历2.4 列表元素的增加操作2.4.1 append()的相关用法2.4.2 e…...

如何学习 Web3

在本文中&#xff0c;我将总结您可以采取的步骤来学习 Web3。从哪儿开始&#xff1f;当我们想要开始新事物时&#xff0c;我们需要一些指导&#xff0c;以免在一开始就卡住。但我们都是不同的&#xff0c;我们有不同的学习方式。这篇文章基于我学习 Web3 的非常个人的经验。路线…...

大数据框架之Hadoop:MapReduce(一)MapReduce概述

1.1MapReduce定义 MapReduce是一个分布式计算框架&#xff0c;用于编写批处理应用程序&#xff0c;是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff0c;并发运行在一…...

一文搞定python语法进阶

前言前面我们已经学习了Python的基础语法&#xff0c;了解了Python的分支结构&#xff0c;也就是选择结构、循环结构以及函数这些具体的框架&#xff0c;还学习了列表、元组、字典、字符串这些Python中特有的数据结构&#xff0c;还用这些语法完成了一个简单的名片管理系统。下…...

2019蓝桥杯真题数列求值(填空题) C语言/C++

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 给定数列 1,1,1,3,5,9,17,⋯&#xff0c;从第 4 项开始&#xff0c;每项都是前 3 项的和。 求第 20190324 项的最后 4 位数字。 运行限制 最大运行时间&#xff1a…...

spring中@Autowire和@Resource的区别在哪里?

介绍今天使用Idea写代码的时候&#xff0c;看到之前的项目中显示有warning的提示&#xff0c;去看了下&#xff0c;是如下代码?Autowire private JdbcTemplate jdbcTemplate;提示的警告信息Field injection is not recommended Inspection info: Spring Team recommends: &quo…...

算法训练营DAY54|583. 两个字符串的删除操作、72. 编辑距离

583. 两个字符串的删除操作 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/delete-operation-for-two-strings/这道题也是对于编辑距离的铺垫题目&#xff0c;是可以操作两个字符串的删除&#xff0c;使得两个字符串的字符完全相同&#xff0c;这道题可…...

【Ctfshow_Web】信息收集和爆破

0x00 信息收集 web1 直接查看源码 web2 查看不了源码&#xff0c;抓包即可看到&#xff08;JS拦截了F12&#xff09; web3 抓包&#xff0c;发送repeater&#xff0c;在响应包中有Flag字段 web4 题目提示后台地址在robots&#xff0c;访问/robots.txt看到Disallow: /fl…...

基于机器学习的推荐算法研究与实现

摘要随着互联网的普及&#xff0c;人们可以通过搜索引擎、社交网络等方式获取大量的信息资源。但是&#xff0c;面对如此之多的信息&#xff0c;人们往往会感到迷失和困惑&#xff0c;无法快速准确地找到自己需要的信息。在这种情况下&#xff0c;推荐算法的出现为我们提供了一…...

(二十四)ATP应用测试平台——springboot集成fastdfs上传与下载功能

前言 本节内容我们主要介绍一下如何在springboot项目中集成fastdfs组件&#xff0c;实现文件的上传与下载。关于fastdfs服务中间键的安装过程&#xff0c;本节内容不做介绍。fastdfs是一个轻量级的分布式文件系统&#xff0c;也是我们文件存储中常常使用的组件之一&#xff0c…...

linux好用命令+vs快捷键

linux好用命令 功能指令跳转到vim界面的最后一行shift键g复制当前路径下所有文件和目录&#xff08;加-r才行&#xff09;到target目录cp -r * /home/target删除指定文件rm -rf test.txt文件重命名&#xff08;-i交互式提示&#xff09;mv -i file1 file2移动某个内容&#xf…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...