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

[C++]——学习模板

了解模板——初阶

  • 前言:
  • 一、模板
    • 1.1 什么是模板
    • 1.2 模板的概念
    • 1.3 模板可以做什么
    • 1.4 泛型模板
  • 二、函数模板
    • 2.1 函数模板概念和格式
    • 2.2 函数模板原理
    • 2.3 函数模板实例化
      • 2.3.1 隐式实例化
      • 2.3.2 显式实例化
    • 2.4 模板参数的匹配原则
    • 2.5 函数模板声明定义分离
  • 三、类模板
    • 3.1 类模板的定义格式
    • 3.2 类模板实例化
    • 3.3 类模板声明和定义分离
  • 四、总结

前言:

什么是模板?模板可以做什么?带着好奇的心态去学习模板一定会有很大的收获。

一、模板

1.1 什么是模板

模板是 C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。

1.2 模板的概念

模板(Template)指 C++ 程序设计设计语言中采用类型作为参数的程序设计,支持通用程序设计。C++的标准库提供许多有用的函数大多结合了模板的观念,如 STL 以及 iostream。

模板是一种对类型进行参数化的工具。
通常有两种形式:函数模板和类模板:

  • 函数模板:针对仅参数类型不同的函数;
  • 类模板:针对仅成员变量和成员函数类型不同的类。

在模版中,编译器一般不会进行类型转换操作,因为一但转化出问题,编译器就要背黑锅。

1.3 模板可以做什么

使用模板的目的就是能够让程序员编写与类型无关的代码.

1.4 泛型模板

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

二、函数模板

函数模板编译(两次):
1:没有实例化之前,检查代码本身是否有语法错误。
2: 实例化期间,检查对模板代码的调用是否合法。

2.1 函数模板概念和格式

概念:

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

格式:

template<typename T1, typename T2,…,typename Tn>
返回值类型 函数名 ( 参数列表 ){}

案例如下:

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

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

2.2 函数模板原理

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

网图:
在这里插入图片描述

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

2.3 函数模板实例化

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

2.3.1 隐式实例化

隐式实例化:也叫推演实例化,函数参数传递,推出模板参数的类型,生成对应的函数。(让编译器根据实参推演模板参数的实际类型)

2.3.2 显式实例化

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

2.4 模板参数的匹配原则

1.一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数
2.对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而 不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数,那么将选择模板。(简单来说就是有现成的就用现成得,有更合适得就用更合适得,没有就将就用模板)
3.模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

2.5 函数模板声明定义分离

可以声明定义分离
不同的是模板参数声明定义都要给

//声明
template<typename T>
void Swap(T& left, T& right);
//定义
template<typename T>
void Swap(T& left, T& right)
{T temp = left;left = right;right = temp;
}

三、类模板

3.1 类模板的定义格式

//可以声明多个模板参数
template<class T1, class T2, ..., class Tn>
class 类模板名
{// 类内成员定义
};

3.2 类模板实例化

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

  • 对于普通类,类名就是类型
  • 对于类模板,类名不是类型,类名<类型>才是整个类的类型

3.3 类模板声明和定义分离

// 类模板
// 注意:Stack不是具体的类,是编译器根据被实例化的类型生成具体类的模具
template<class T>
class Stack
{
private:T* _a;size_t _top;size_t _capacity;public:// ...Stack(size_t capacity = 10):_a(new T[capacity]),_top(0),_capacity(capacity){}~Stack(); // 析构函数,在类中声明,类外定义
};// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template<class T>
Stack<T>::~Stack()
{if (_a){delete[] _a;_a = nullptr;}_top = _capacity = 0;
}int main()
{// 类模板的使用都是显式实例化// Stack是类名,Stack<int>才是类型Stack<int*> st1;Stack<int> st2;return 0;
}

注意: 模板不支持把声明写到 .h 头文件,定义写到 .cpp 源文件的这种声明与定义分离在不同文件中的方式,会出现链接错误。

四、总结

注意: 一个模板,如果没有实例化,编译器是不会去检查它内部的语法的。

优点:

  1. 模板复用了代码,节省资源,更快的迭代开发, C++ 的标准模板库 (STL) 因此而产生
  2. 增强了代码的灵活性

缺点:

  1. 模板会导致代码膨胀问题,也会导致编译时间变长
  2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误

相关文章:

[C++]——学习模板

了解模板——初阶 前言&#xff1a;一、模板1.1 什么是模板1.2 模板的概念1.3 模板可以做什么1.4 泛型模板 二、函数模板2.1 函数模板概念和格式2.2 函数模板原理2.3 函数模板实例化2.3.1 隐式实例化2.3.2 显式实例化 2.4 模板参数的匹配原则2.5 函数模板声明定义分离 三、类模…...

大数据技术14:FlinkCDC数据变更捕获

前言&#xff1a;Flink CDC是Flink社区开发的flink-cdc-connectors 组件&#xff0c;这是⼀个可以直接从 MySQL、PostgreSQL 等数据库直接读取全量数据和增量变更数据的 source 组件。 https://github.com/ververica/flink-cdc-connectors 一、CDC 概述 CDC 的全称是 Change …...

SpringDataRedis 基本使用

1.1 简介 1.1.1 概述 Spring Data 中有一个成员 Spring Data Redis&#xff0c;他提供了 RedisTemplate 可以在 Spring 应用中更简便的访问 Redis 以及异常处理及序列化&#xff0c;支持发布订阅等操作。 1.2 RedisTemplate 常见 API   RedisTemplate 针对 jedis 客户端中大…...

蓝牙物联网智慧工厂解决方案

蓝牙物联网智慧工厂解决方案是一种针对工厂管理的智能化解决方案&#xff0c;通过蓝牙、物联网、大数据、人工智能等技术&#xff0c;实现工厂人员的定位、物资的定位管理、车间的智慧巡检、智慧安防以及数据的可视化等功能。 蓝牙物联网智慧工厂解决方案构成&#xff1a; 人员…...

html的学习笔记

开发工具&#xff1a;vscode 文字标签 h1:一级标题&#xff0c;h2&#xff1a;二级标题h6 p&#xff1a;段落标签 hr&#xff1a;分隔线 br&#xff1a;换行 strong/b&#xff1a;文字加粗 ins/u:下划线 em/i&#xff1a;倾斜 del/s&#xff1a;删除线 媒体标签 图片…...

每日一道算法题 8(2023-12-16)

题目描述 给定一个仅包含0和1的n*n二维矩阵 请计算二维矩阵的最大值 计算规则如下 每行元素按下标顺序组成一个二进制数(下标越大约排在低位)&#xff0c; 二进制数的值就是该行的值&#xff0c;矩阵各行之和为矩阵的值 允许通过向左或向右整体循环移动每个元素来改变元素在行…...

Unity项目优化案例二

本文地址&#xff1a;https://blog.csdn.net/t163361/article/details/135024136 针对工作中遇到的优化问题&#xff0c;记录一下&#xff0c;给大家优化自己的项目提供一些思路。 公司产品最近正给国内某大型赛事做支撑服务暴露出不少问题。 使用环境 Unity 2021.3.0f1 cpu…...

如何发布自定义 npm 组件包

准备工作 1. 注册 npm 账号 还没有 npm 账号&#xff1f;去官网注册&#xff1a; https://www.npmjs.com 需要记住用户名、密码、邮箱&#xff0c;后面需要用到。 2. 查看本地 npm 镜像&#xff0c;如果不是默认的&#xff0c;需要改回来 npm config get registry重置镜像路…...

iOS_给View的部分区域截图 snapshot for view

文章目录 1.将整个view截图返回image&#xff1a;2.截取view的部分区域&#xff0c;返回image&#xff1a;3.旧方法&#xff1a;4.Tips参考&#xff1a; 1.将整个view截图返回image&#xff1a; 这些 api 已被废弃&#xff0c;所以需要判断 iOS 版本 写两套代码&#xff1a; R…...

计算机网络——数据链路层-可靠传输的实现机制:回退N帧协议GBN(无差错情况、累积确认、有差错情况、发送窗口尺寸)

目录 回退N帧协议GBN 介绍 无差错情况 累积确认 有差错情况 发送窗口尺寸 小结 练习 解析 示意图 上篇中所介绍的停止-等待协议的信道利用率很低&#xff1b;若出现超时重传&#xff0c;则信道利用率更低。 如果发送方在收到接收方的确认分组之前可以连续发送多个数…...

IDEA debug窗口左边工具栏隐藏与显示

今天在debug排查代码的时候一不小心点到哪里&#xff0c;结果变成这样 我们可以这样恢复&#xff0c;右键Debug 点击show Toolbar...

WPF 基于TableControl的页面切换

文章目录 前言其它项目的UserControl切换TableControl添加按钮&#xff0c;隐去TableItem的Header 结论 前言 我想用WPF简单实现一个按钮视图切换的效果&#xff0c;但是我发现别人的实现效果非常的麻烦。 其它项目的UserControl切换 我网上找了个开源的项目&#xff0c;他是…...

Lua 元表,元方法

元表与元方法的概念 Lua中每个值都可具有元表。元表是普通的Lua表,定义了原始值在某些特定操作下 的行为。 例如,当table作为加法的操作数时,Lua检查其“元表”中的“__add”字段是否有 个函数。如果有,Lua调用它执行加法。我们称“元表”中的“键(如__add)”为事件(event),称…...

C# WPF上位机开发(利用tcp/ip网络访问plc)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 c# wpf如果是用来开发非标上位机的&#xff0c;那么和plc的通信肯定是少不了的。而且&#xff0c;大部分plc都支持modbus协议&#xff0c;所以这个…...

Knife4j 接口文档如何设置 Authorization 鉴权参数?

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…...

CentOS 防火墙管理及使用的redis基本常用命令

文章目录 防火墙管理使用systemctl管理防火墙启动、关闭使用firewalld-cmd配置访问防火墙策略firewalld配置文件修改限制来源IP docker使用 redis 防火墙管理 需要关闭防火墙或者开启对应端口 使用systemctl管理防火墙启动、关闭 启动防火墙&#xff1a; systemctl start fi…...

路由器原理

目录 一.路由器 1.路由器的转发原理 2.路由器的工作原理 二.路由表 1.路由表的形成 2.路由表表头含义 直连&#xff1a; 非直连&#xff1a; 静态 静态路由的配置 负载均衡&#xff08;浮动路由&#xff09; 默认路由 动态 三.交换与路由对比 一.路由器 1.路由器…...

采埃孚4D成像雷达拆解

1 基本信息 品牌&#xff1a;海外Tier1采埃孚 • 应用&#xff1a;上汽飞凡中高端纯电平台 • 数量&#xff1a;单车2个&#xff0c;安装在前后保内部 • 最远探测距离&#xff1a;350米 拆解来看&#xff0c;4D雷达主要可以分为4个部分&#xff0c;分别为数字接口板及结构件…...

若依框架springboot——修改前端图片上传样式

简述 使用过若依框架的&#xff0c;一定知道若依前端框架上传图片的样式&#xff0c;是一个正方形加号图片&#xff0c;但是如果你要使用自定义样式呢。 比如将下面这个图进行修改呢 修改后的样式 你可以直接找到element-ui 修改上传图片的组件&#xff0c;也可以加入新的组…...

mysql 数据库 关于库的基本操作

库的操作 如果想到 mysql 客户端当中数据 系统当中的命令的话&#xff0c;直接输入的话&#xff0c;会被认为是 mysql 当中的命令。 所以&#xff0c;在mysql 当中执行系统当中的命令的话&#xff0c;要在系统命令之前带上 ststem &#xff0c;表示系统命令&#xff1a; 但是…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...