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

C++新经典模板与泛型编程:SFINAE替换失败并不是一个错误

替换失败并不是一个错误(SFINAE)

  • SFINAE是一个英文简称,全称为Substitution Failure is not an Error,翻译成中文就是“替换失败并不是一个错误”。

  • SFINAE可以看作C++语言的一种特性或模板设计中要遵循的一个重要原则,非常重要,务必要理解好。

  • 这个特性显然还是针对函数模板的重载而言的。例如,前面代码中既有对myfunc()函数的实现,又有对myfunc()函数模板的实现,那么当调用myfunc()时,编译器如何选择呢?编译器首先必须要针对函数模板确定哪些具体的模板参数比较合适。例如,调用myfunc(15);时,对于myfunc()函数模板,编译器会认为类型模板参数T应该为int类型才比较合适,此时,编译器就会用int这个类型替换myfunc()函数模板中的T,替换完毕之后,编译器会根据一套自己内部的规则判断到底是调用myfunc()函数模板合适,还是调用myfunc()函数合适。总之,编译器最终的目的就是看调用谁合适,是函数还是函数模板。

  • 但是,对于函数模板,当用一个具体类型替换模板参数时,可能会产生意想不到的问题,如产生一些毫无意义的甚至是看起来语法上错误的代码,对于这些代码,编译器的处理方法并不一定是报错,有可能是忽略,编译器认为这个函数模板不匹配针对本次的函数调用,就当这个函数模板不存在一样(想象去机场接某个客人,接机者会根据样貌分辨客人,发现样貌不像的,会直接忽略此人),转而去选择其他更匹配的函数或函数模板。这就是所谓的“替换失败并不是一个错误”这个说法的由来。看一个范例,首先写一个名为mydouble()的函数模板:

  • 为什么是这种错误呢?不难想象,当调用mydouble()的时候,因为传入的是一个数字15,所以编译器认为15是int类型比较合适,于是,编译器就会用int替换mydouble()函数模板中的T。一般来说,编译器做这个替换只会替换函数模板的声明部分,函数体部分编译器不会去替换,替换之后,大概mydouble()函数模板的声明部分就应该如下。

int::size_type mydouble(const int& t);
  • 这个语法显然是错误的,要是直接写这行代码,编译器会报如下错误

"size_type": 不是"global namespace’"的成员`

  • 但是,因为这里编译器只是尝试用int类型替换mydouble()函数模板得到的结果代码,所以编译器其实并不认为mydouble()函数模板有错,这就是所谓的“替换失败并不是一个错误”(替换失败就失败了,对于int类型,并不存在size_type成员,那没准对于其他类型就存在size_type成员呢),但为什么报“mydouble”:未找到匹配的重载函数的错误呢?这是因为在main()主函数中对mydouble()进行调用的时候,mydouble()这个函数模板不合适,但又找不到其他适合调用的mydouble(),所以编译器才会报这个错误。要解决这个报错问题,提供一个适合调用的mydouble()函数就可以了,增加如下mydouble()函数:
#include "killCmake.h"using namespace std;template<typename T>
typename T::size_type my_double(const T& t)
{return t[0] * 2;
}int my_double(int i)
{return i * 2;
}int main()
{my_double(15);return 0;
}
  • 这样,mydouble(15);代码行就会直接调用mydouble()函数。
  • 如果在main()主函数中添加代码:
#include "killCmake.h"#include <vector>
using namespace std;template<typename T>
typename T::size_type my_double(const T& t)
{return t[0] * 2;
}int my_double(int i)
{return i * 2;
}int main()
{// error C2672: “my_double”: 未找到匹配的重载函数my_double(15);std::vector<int> my_vec;my_vec.push_back(15);std::cout << my_double(my_vec) << std::endl;return 0;
}

在这里插入图片描述

  • 上述代码调用的就是mydouble()函数模板。总结一下SFINAE的特性:我(编译器)虽然看不出你(实例化了的模板)的对错(错误一般指无效的类型、无效的表达式等),但是我能决定是否选择你,当我觉得不合适的时候,我虽然不说你错,但我会忽略你(而不会选择你)。

相关文章:

C++新经典模板与泛型编程:SFINAE替换失败并不是一个错误

替换失败并不是一个错误&#xff08;SFINAE&#xff09; SFINAE是一个英文简称&#xff0c;全称为Substitution Failure is not an Error&#xff0c;翻译成中文就是“替换失败并不是一个错误”。 SFINAE可以看作C语言的一种特性或模板设计中要遵循的一个重要原则&#xff0c;…...

基于若依的ruoyi-nbcio流程管理系统支持支持定时边界事件和定时捕获事件

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 1、定时边界事件 <template><div class"panel-tab__content"><!--目前只处理定…...

递归-极其优雅的问题解决方法(Java)

递归的定义 大名鼎鼎的递归&#xff0c;相信你即使没接触过也或多或少听过&#xff0c;例如汉诺塔问题就是运用了递归的思想&#xff0c;对于一些学过c语言的同学来说&#xff0c;它可能就是噩梦&#xff0c;因为我当时就是这么认为的&#xff08;不接受反驳doge&#xff09; …...

VSCode搭建STM32开发环境

1、下载安装文件 链接&#xff1a;https://pan.baidu.com/s/1WnpDTgYBobiZaXh80pn5FQ 2、安装VSCodeUserSetup-x64-1.78.2.exe软件 3、 在VSCode中安装必要的插件 3、配置Keil Assistant插件 4、在环境变量中部署mingw64编译环境...

解决CentOS下PHP system命令unoconv转PDF提示“Unable to connect or start own listener“

centos系统下&#xff0c;用php的system命令unoconv把word转pdf时提示Unable to connect or start own listene的解决办法 unoconv -o /foo/bar/public_html/upload/ -f pdf /foo/bar/public_html/upload/test.docx 2>&1 上面这个命令在shell 终端能执行成功&#xff0c…...

软件测试外包干了2个月,技术进步2年。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;18年通过校招进入北京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年国庆&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…...

Linux-网络服务和端口

域名&#xff1a;便于人们记忆和使用的标识符 www.baidu.com域名解析&#xff1a;将域名转换为与之对应的 IP 地址的过程 nameserver 8.8.8.8ip地址&#xff1a;网络设备的唯一数字标识符 域名ip地址localhost127.0.0.1 网络服务和端口 网络服务端口ftp21ssh22http80https…...

Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)读书笔记 目录

完结状态&#xff1a;未完结 文章目录 前言第1章 Kubernetes入门 11.1 了解Kubernetes 2 附录A Kubernetes核心服务配置详解 915总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; Kubernetes权威指南&#xff1a;从Docker到Kubernetes实践全接触&…...

阿里云Arthas使用——通过watch命令查看类的返回值 捞数据出来

前言 Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法执行耗时&#xff0c;类…...

Redis中持久化策略RDB与AOF优缺点对比

Redis持久化策略对比 RDBAOF持久化方式定时对整个内存做快照记录每一次执行的命令数据完整性不完整,两次备份之间存在丢失相对完整,取决于刷盘策略文件大小会有压缩,文件体积小记录命令,文件体积较大宕机恢复速度很快慢数据恢复优先级低,数据完整性不如AOF高,记录了执行命令数据…...

通用plantuml 时序图(Sequence Diagram)模板头

通用plantuml文件 startuml participant Admin order 0 #87CEFA // 参与者、顺序、颜色 participant Student order 1 #87CEFA participant Teacher order 2 #87CEFA participant TestPlayer order 3 #87CEFA participant Class order 4 #87CEFA participant Subject order …...

Domino多Web站点托管

大家好&#xff0c;才是真的好。 看到一篇文档&#xff0c;大概讲述的是他在家里架了一台Domino服务器&#xff0c;上面跑了好几个Internet的Web网站&#xff08;使用Internet站点&#xff09;。再租了一台云服务器&#xff0c;上面安装Nginx做了反向代理&#xff0c;代理访问…...

防火墙补充NAT

目录 1.iptables保存规则 2.自定义链 3.NAT NAT的实现分为下面类型&#xff1a; SNAT实验操作 DNAT实验操作 1.iptables保存规则 永久保存方法一&#xff1a; iptables -save > /data/iptables_rule //输出重定向备份 iptables -restore < /data/iptables_r…...

配置和管理VLAN

VLAN技术是交换技术的重要组成部分&#xff0c;也是交换机配置的基础。用于把物理上直接相连的网络从逻辑上划分为多个子网。 每一个VLAN 对应一个广播域&#xff0c;处于不同VLAN 上的主机不能通信。 不同VLAN 之间通信需要引入三层交换技术。 对性能局域网的配置和管理主要…...

dtaidistance笔记:dtw_ndim (高维时间序列之间的DTW)

1 数据 第一个维度是sequence的index&#xff0c;每一行是多个元素&#xff08;表示这一时刻的record&#xff09; from dtaidistance.dtw_ndim import *s1 np.array([[0, 0],[0, 1],[2, 1],[0, 1],[0, 0]], dtypenp.double) s2 np.array([[0, 0],[2, 1],[0, 1],[0, .5],[0…...

2 文本分类入门:TextCNN

论文链接&#xff1a;https://arxiv.org/pdf/1408.5882.pdf TextCNN 是一种用于文本分类的卷积神经网络模型。它在卷积神经网络的基础上进行了一些修改&#xff0c;以适应文本数据的特点。 TextCNN 的主要思想是使用一维卷积层来提取文本中的局部特征&#xff0c;并通过池化操…...

算法初阶双指针+C语言期末考试之编程题加强训练

双指针 常⻅的双指针有两种形式&#xff0c;⼀种是对撞指针&#xff0c;⼀种是左右指针。 对撞指针&#xff1a;⼀般⽤于顺序结构中&#xff0c;也称左右指针。 • 对撞指针从两端向中间移动。⼀个指针从最左端开始&#xff0c;另⼀个从最右端开始&#xff0c;然后逐渐往中间逼…...

【Spark基础】-- 宽窄依赖

目录 1、前言 2、宽窄依赖 2.1 窄依赖 2.2 宽依赖 3、宽窄转换的算子 1、前言 要理解宽窄依赖,首先我们需要了解 Transform...

Spatial Data Analysis(六):空间优化问题

Spatial Data Analysis&#xff08;六&#xff09;&#xff1a;空间优化问题 使用pulp库解决空间优化问题&#xff1a; pulp是一个用于优化问题的Python库。它包含了多种优化算法和工具&#xff0c;可以用于线性规划、混合整数线性规划、非线性规划等问题。Pulp提供了一个简单…...

PHP短信接口防刷防轰炸多重解决方案三(可正式使用)

短信接口盗刷轰炸&#xff1a;指的是黑客利用非法手段获取短信接口的访问权限&#xff0c;然后使用该接口发送大量垃圾短信给目标用户 短信验证码轰炸解决方案一(验证码类解决)-CSDN博客 短信验证码轰炸解决方案二(防止海外ip、限制ip、限制手机号次数解决)-CSDN博客 PHP短信…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...