深蓝学院C++基础与深度解析笔记 第13章 模板
1. 函数模板
● 使用 template 关键字引入模板:
template<typename T> //声明:T模板形参void fun(T); // T 函数形参template<typename T> //定义void fun(T) {...}
– 函数模板不是函数
– typename 关键字可以替换为 class ,含义相同
– 函数模板中包含了两对参数:函数形参 / 实参;模板形参 / 实参
● 函数模板的显式实例化(生成函数): fun<int>(3)
– 实例化会使得编译器产生相应的函数(函数模板并非函数,不能调用)
– 编译期的两阶段处理● 有限的模板语法检查● 模板实例化
– 模板必须在实例化时可见, 翻译单元的一处定义原则
– 注意与内联函数的异同:都是翻译单元的一处定义原则,模板是调用,内联是引入
● 函数模板的重载
参数个数重载:

参数重载为指针:

● 模板实参的类型推导 :参考文献
– 如果函数模板在实例化时没有显式指定模板实参,那么系统会尝试进行推导
– 推导是基于函数实参(表达式)确定模板实参的过程,其基本原则与 auto 类型推导相似● 函数形参是左值引用 / 指针:– 忽略表达式类型中的引用– 将表达式类型与函数形参模式匹配以确定模板实参● 函数形参是万能引用int&& x = 3; – 如果实参表达式是右值,确定值那么模板形参被推导为去掉引用的基本类型– 如果实参表达式是左值,那么模板形参被推导为左值引用,触发引用折叠● 函数形参不包含引用– 忽略表达式类型中的引用– 忽略顶层 const– 数组、函数转换成相应的指针类型● 第一个函数形参十分重要

● 模板实参并非总是能够推导得到
– 如果模板形参与函数形参无关,则无法推导
– 即使相关,也不一定能进行推导,推导成功也可能存在因歧义而无法使用
● 在无法推导时,编译器会选择使用缺省模板实参
– 可以为任意位置的模板形参指定缺省模板实参 注意与函数缺省实参的区别
函数参数有默认值的时候,它的右边的参数一定要有默认值,
模板参数有默认值的时候,它的右边的参数不一定要有默认值,
● 显式指定部分模板实参
– 显式指定的模板实参必须从最左边开始,依次指定
– 模板形参的声明顺序会影响调用的灵活性
● 函数模板制动推导时会遇到的几种情况
– 函数形参无法匹配—— SFINAE (替换失败并非错误)
– 模板与非模板同时匹配,匹配等级相同,此时选择非模板的版本
– 多个模板同时匹配,此时采用偏序关系确定选择 最特殊 的版本
● 函数模板的实例化控制
– 显式实例化定义(只声明先不调用 ): template void fun<int>(int) / template void fun(int)
– 显式实例化声明: extern template void fun<int>(int) / extern template void fun(int)
– 注意一处定义原则
– 注意实例化过程中的模板形参推导,按代码出现顺序
● 函数模板的 ( 完全 ) 特化: 注意尖括号
template<> void f<int>(int) / template<> void f(int)
本质是一个实例
– 并不引入新的(同名)名称,只是为某个模板针对特定模板实参提供优化算法,
– 注意与重载的区别
– 注意特化过程中的模板形参推导
● 避免使用函数模板的特化: 视频参考资料
– 不参与重载解析,会产生反直觉的效果
– 通常可以用重载代替
– 一些不便于重载的情况:无法建立模板形参与函数形参的关联,可以 ● 使用 if constexpr 解决● 引入假函数形参 “ ”● 通过类模板特化解决
●(C++20) 函数模板的简化形式:使用 auto 定义模板参数类型
– 优势:书写简捷
– 劣势:在函数内部需要间接获取参数类型信息
2. 类模板与成员函数模板
● 使用 template 关键字引入模板: template<typename T> class B {…};
– 类模板的声明与定义 翻译单元的一处定义原则 ——
– 成员函数只有在调用时才会被实例化,节省空间
– 类内类模板名称的简写
– 类模板成员函数的定义(类内、类外)● 模板类内可以有模板函数
● 成员函数模板
– 类的成员函数模板
– 类模板的成员函数模板
● 友元函数(模板)
– 可以声明一个函数模板为某个类(模板)的友元
– C++11 支持声明模板参数为友元,but 用途不大
● 类模板的实例化: 更多内容
– 与函数实例化很像
– 可以实例化整个类,或者类中的某个成员函数
● 类模板的(完全)特化 / 部分特化(偏特化)
– 特化版本与基础版本可以拥有完全不同的实现
● 类模板的实参推导(从 C++17 开始)
– 基于构造函数的实参推导
– 用户自定义的推导指引
– 注意:引入实参推导并不意味着降低了类型限制!
– C++ 17 之前的解决方案:引入辅助模板函数
3. Concepts
● 模板的问题:没有对模板参数引入相应的限制
– 参数是否可以正常工作,通常需要阅读代码进行理解
– 编译报错友好性较差 (vector<int&>)
● ( C++20 ) Concepts :编译期谓词,基于给定的输入,返回 true 或 false进行限制
– 与 constraints ( require 从句)一起使用限制模板参数
– 通常置于表示模板形参的尖括号后面进行限制
● Concept 的定义与使用
– 包含一个模板参数的 Concept:
● 使用 requires 从句● 直接替换 typename
– 包含多个模板参数的 Concept:
● 用做类型 constraint 时,少传递一个参数,推导出的类型将作为首个参数
● requires 表达式
– 简单表达式:表明可以接收的操作
– 类型表达式:表明是一个有效的类型:typename
– 复合表达式:表明操作的有效性,以及操作返回类型的特性
– 嵌套表达式:包含其它的限定表达式,也可以包含requires嵌套
● 注意区分 requires 从句与 requires 表达式
●requires 从句会影响重载解析与特化版本的选取
– 只有 requires 从句有效而且返回为 true 时相应的模板才会被考虑
– requires 从句所引入的限定具有偏序特性,系统会选择限制最严格的版本
● 特化小技巧:在声明中引入“ A||B” 进行限制,之后分别针对 A 与 B 引入特化
4. 模板相关内容
数值模板参数与模板模板参数
● 模板可以接收(编译期常量)数值作为模板参数
– template <int a> class Str; //数值要有一个类型
– template <typename T, T value> class Str;
– (C++ 17) template <auto value> class Str;
– (C++ 20) 接收字面值类对象与浮点数作为模板参数● 目前 clang 12 不支持接收浮点数作为模板参数
● 接收模板作为模板参数
– template <template<typename T> class C> class Str;
– (C++17) template <template<typename T> typename C> class Str;
– C++17 开始,模板的模板实参考虑缺省模板实参(clang 12 支持程度有限)
● Str 是否支持?
别名模板与变长模板
● 可以使用 using 引入别名模板
– 为模板本身引入别名
– 为类模板的成员引入别名
– 别名模板不支持特化,但可以基于类模板的特化引入别名,以实现类似特化的功能● 注意与实参推导的关系,要求确定能推导出来才行
● 变长模板( Variadic Template )

– 变长模板参数与参数包
– 变长模板参数可以是数值、类型或模板
– sizeof... 操作
– 注意变长模板参数的位置
包展开与折叠表达式
●(C++11) 通过包展开技术操作变长模板参数
– 包展开语句可以很复杂,需要明确是哪一部分展开,在哪里展开
●(C++17) 折叠表达式 (cpp reference)
– 基于逗号的折叠表达式应用
– 折叠表达式用于表达式求值,无法处理输入(输出)是类型与模板的情形
完美转发与 lambda 表达式模板
● (C++11) 完美转发: std::forward 函数
– 通常与万能引用结合使用
– 同时处理传入参数是左值或右值的情形
●(C++20) lambda表达式模板
歧义与变量模板
● 使用 typename 与 template 消除歧义
– 使用 typename 表示一个依赖名称是类型而非静态数据成员
– 使用 template 表示一个依赖名称是模板
– template 与成员函数模板调用
●(C++14) 变量模板
– template T pi = (T)3.1415926;
– 其它形式的变量模板
相关文章:
深蓝学院C++基础与深度解析笔记 第13章 模板
1. 函数模板 ● 使用 template 关键字引入模板: template<typename T> //声明:T模板形参void fun(T); // T 函数形参template<typename T> //定义void fun(T) {...}– 函数模板不是函数 –…...
装饰器模式——扩展系统功能
1、简介 1.1、概述 对新房进行装修并没有改变房屋用于居住的本质,但它可以让房子变得更漂亮、更温馨、更实用、更能满足居家的需求。在软件设计中,也有一种类似新房装修的技术可以对已有对象(新房)的功能进行扩展(装…...
无涯教程-jQuery - jQuery.get( url, data, callback, type )方法函数
jQuery.get(url,[data],[callback],[type])方法使用GET HTTP请求从服务器加载数据。 该方法返回XMLHttpRequest对象。 jQuery.get( url, [data], [callback], [type] ) - 语法 $.get( url, [data], [callback], [type] ) 这是此方法使用的…...
【Vue3】递归组件
1. 递归组件mock数据 App.vue <template><div><Tree :data"data"></Tree></div> </template><script setup lang"ts"> import { reactive } from vue; import Tree from ./components/Tree.vue; interface Tr…...
【Python】数据分析+数据挖掘——探索Pandas中的索引与数据组织
前言 在数据科学和数据分析领域,Pandas是一个备受喜爱的Python库。它提供了丰富的数据结构和灵活的工具,帮助我们高效地处理和分析数据。其中,索引在Pandas中扮演着关键角色,它是一种强大的数据组织和访问机制,使我们…...
matlab进阶:求解在约束条件下的多元目标函数最值(fmincon函数详解)
🌅*🔹** φ(゜▽゜*)♪ **🔹*🌅 欢迎来到馒头侠的博客,该类目主要讲数学建模的知识,大家一起学习,联系最后的横幅! 喜欢的朋友可以关注下,私信下次更新不迷路࿰…...
Kotlin知识点
Kotlin 是 Google 推荐的用于创建新 Android 应用的语言。使用 Kotlin,可以花更短的时间编写出更好的 Android 应用。 基础 Kotlin 程序必须具有主函数,这是 Kotlin 编译器在代码中开始编译的特定位置。主函数是程序的入口点,或者说是起点。…...
亚马逊云科技联合霞光社发布《2013~2023中国企业全球化发展报告》
中国企业正处于全球聚光灯下。当企业全球化成为时代发展下的必然趋势,出海也从“可选项”变为“必选项”。中国急速扩大的经济规模,不断升级的研发和制造能力,都在推动中国企业不断拓宽在全球各行业的疆域。 过去十年,是中国企业…...
【解析excel】利用easyexcel解析excel
【解析excel】利用easyexcel解析excel POM监听类工具类测试类部分测试结果备注其他 EasyExcel Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题&…...
JQuery操作单选按钮Radio和复选框checkbox
获取选中值: $(input:radio:checked).val();$("input[typeradio]:checked").val();$("input[namerd]:checked").val();$("input[idrand_question]:checked").val();设置第一个Radio为选中值: $(input:radio:…...
7.28 作业 QT
手动完成服务器的实现,并具体程序要注释清楚: widget.h: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器类 #include <QTcpSocket> //客户端类 #include <QMessageBox> //对话框类 #include …...
HTML <pre> 标签
定义和用法 pre 元素可定义预格式化的文本。被包围在 pre 元素中的文本通常会保留空格和换行符。而文本也会呈现为等宽字体。 <pre> 标签的一个常见应用就是用来表示计算机的源代码。 可以导致段落断开的标签(例如标题、"><p> 和 标签"><a…...
查询结果元数据-MetaData对象、数据库工具类的封装、通过反射实现数据查询的封装
六、查询结果元数据-MetaData对象 七、数据库工具类的封装 1、PropertieUtil类 2、DbUtil类 3、DBHepler类 查询: 4、TestDb测试类: 更新: 1)插入: 2)修改: 3)删除: 查…...
【Minio中间件】上传图片并Vue回显
流程: 目录 1.文件服务器Minio的安装 1.1 下载Minio安装后,新建1个data文件夹。并在该安装目录cmd 敲命令。注意不要进错目录。依次输入 1.2 登录Minio网页端 1.3 先建1个桶(buckets),点击create a bucket 2. Spr…...
Jmeter配置不同业务请求比例,应对综合场景压测
需求: 每次向服务器发出请求时,先生成一个随机数,我们对随机数的取值划分若干个范围(对应若干个业务请求),然后对随机数进行判断,当随机数落在某个范围内,就可以执行对应的请求。比…...
数学分析:流形的线性代数回顾
因为是线性的,所以可以把所有的系数都提取出去。这也是多重线性代数的性质。可以看成基本的各项自变量的乘法。 这里可以看到两个不同基向量下,他们的坐标转化关系。 引出了张量积,也就是前面提到的内容。 对偶空间的例子总是比较美好。 因为…...
前端请求后端接口返回错误码
1、如果 HTTP Code 是 2xx 范围内的,那通常表明请求已经成功处理,并且可以根据具体的 HTTP Code 进一步判断请求的处理结果。比如: HTTP Code 200 表明请求成功,并返回了请求资源;HTTP Code 204 表明请求成功…...
【Java Web】Nacos 介绍和安装教程
文章目录 1. Nacos 介绍1.1 Nacos 的定义1.2 Nacos 的主要功能1.2.1 服务注册与发现1.2.2 配置管理1.2.3 动态 DNS 服务1.2.4 服务和元数据管理 1.3 Nacos 的适用场景1.3.1 微服务架构1.3.2 动态配置管理1.3.3 多环境部署1.3.4 云原生应用 2. Nacos 的核心组件2.1 服务注册与发…...
web漏洞-java安全(41)
这个重点是讲关于java的代码审计,看这些漏洞是怎么在java代码里面产生的。 #Javaweb 代码分析-目录遍历安全问题 这个漏洞原因前面文章有,这次我们看看这个漏洞如何在代码中产生的,打开靶场 解题思路就是通过文件上传,上传文件…...
用CSS和HTML写一个水果库存静态页面
HTML代码: <!DOCTYPE html> <html> <head><link rel"stylesheet" type"text/css" href"styles.css"> </head> <body><header><h1>水果库存</h1></header><table>…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
李沐--动手学深度学习--GRU
1.GRU从零开始实现 #9.1.2GRU从零开始实现 import torch from torch import nn from d2l import torch as d2l#首先读取 8.5节中使用的时间机器数据集 batch_size,num_steps 32,35 train_iter,vocab d2l.load_data_time_machine(batch_size,num_steps) #初始化模型参数 def …...
6.计算机网络核心知识点精要手册
计算机网络核心知识点精要手册 1.协议基础篇 网络协议三要素 语法:数据与控制信息的结构或格式,如同语言中的语法规则语义:控制信息的具体含义和响应方式,规定通信双方"说什么"同步:事件执行的顺序与时序…...
