constexpr与std::is_same_v碰撞会产生什么火花?

1. 只编译会用到的if分支

示例代码一中,checkType_v1checkType_v2两个函数的区别就是if的条件里一个加了constexpr一个没加,加与不加从结果来看都一样,那在编译时和运行时各有什么区别呢?

示例代码一test_01.cpp

// g++  test_01.cpp  -std=c++17#include <iostream>
#include <type_traits>template<class T>
void checkType_v1(T){if constexpr (std::is_same_v<T, int>){std::cout << "Input is an int.\n";}else if constexpr (std::is_same_v<T, float>){std::cout << "Input is a float.\n";}else if constexpr (std::is_same_v<T, double>){std::cout << "Input is a double.\n";}else{std::cout << "Unsupported type!\n";}
}template<class T>
void checkType_v2(T){if (std::is_same_v<T, int>){std::cout << "Input is an int.\n";}else if (std::is_same_v<T, float>){std::cout << "Input is a float.\n";}else if (std::is_same_v<T, double>){std::cout << "Input is a double.\n";}else{std::cout << "Unsupported type!\n";}
}int main(){checkType_v1(4);   // Input is an int.checkType_v1(4.f); // Input is a float.checkType_v1(4.0); // Input is a double.checkType_v1('A'); // Unsupported type!checkType_v2(4);   // Input is an int.checkType_v2(4.f); // Input is a float.checkType_v2(4.0); // Input is a double.checkType_v2('A'); // Unsupported type!    
}

【来自C++大咖吴老师的解答】如果你要调用一个只接受某种类型的函数,那就必须用 if constexpr。此外,用 if constexpr 条件判断是编译是做出的,没用到的分支完全不会在某个类型的特化里产生二进制代码。

举例说明,也就是说针对checkType_v1的版本,假设调用它的时候传入的是int类型的参数,那么编译的二进制文件中只有代码里的第一个分支的实现。而checkType_v2的版本的二进制文件中是有整个函数的实现。

这么做的目的有如下三个(其中第三个最重要):

  1. 降低运行时的判断时间;
  2. 减少编译后二进制文件的大小;
  3. 【来自C++大咖吴老师的解答】但最重要的是,有些情况下你对特定类型要走的分支在其他类型的情况下可能完全编译不通过!比如,vector可以reservedeque不可以;deque可以push_frontvector不可以。

2. 验证上面第3点

示例代码二test_02.cpp

// g++  test_02.cpp  -std=c++17
#include <iostream>
#include <type_traits>
#include <typeinfo>
#include <vector>
#include <set>
#include <deque>template<class Container>
void expandContainer(Container& container, int val){if constexpr (std::is_same_v<Container, std::vector<int>>){container.push_back(val);for(const auto&it: container){std::cout << it << ", ";}std::cout << "vector number added.\n";}else if constexpr (std::is_same_v<Container, std::deque<int>>){container.push_front(val);for(const auto&it: container){std::cout << it << ", ";}std::cout << "deque number added.\n";}else{container.insert(val);for(const auto&it: container){std::cout << it << ", ";}std::cout << "Other container number added.\n";}
}int main(){std::vector<int> vec{1,2,3};expandContainer(vec,100);     // 1, 2, 3, 100, vector number added.std::deque<int> deq{4,5,6};expandContainer(deq, 200);    // 200, 4, 5, 6, deque number added.std::set<int> aset{7,8,9};expandContainer(aset, 300);   // 7, 8, 9, 300, Other container number added.

假如去掉constexpr,如示例代码三test_03.cpp

#include <iostream>
#include <type_traits>
#include <typeinfo>
#include <vector>
#include <set>
#include <deque>template<class Container>
void expandContainer(Container& container, int val){if constexpr (std::is_same_v<Container, std::vector<int>>){container.push_back(val);for(const auto&it: container){std::cout << it << ", ";}std::cout << "vector number added.\n";}else if /*constexpr*/ (std::is_same_v<Container, std::deque<int>>){container.push_front(val);for(const auto&it: container){std::cout << it << ", ";}std::cout << "deque number added.\n";}else{container.insert(val);for(const auto&it: container){std::cout << it << ", ";}std::cout << "Other container number added.\n";}
}int main(){std::vector<int> vec{1,2,3};expandContainer(vec,100);     // 1, 2, 3, 100, vector number added.//std::deque<int> deq{4,5,6};//expandContainer(deq, 200);    // 200, 4, 5, 6, deque number added.std::set<int> aset{7,8,9};expandContainer(aset, 300);   // 7, 8, 9, 300, Other container number added.
}

此时编译会有如下报错:
在这里插入图片描述
走哪个分支如果在编译时无法确定那么就要保障运行时所有的分支都可以走,很显然else if的分支中有push_front操作,但std::set不支持,所以编译会报错。
因此,如果传入的参数只能走特定的分支,只能在编译时就限制住走的路径,即使用if constexprelse if constexpr

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/779684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ctfshow靶场sql注入wp

目录 web171 web172 web173 web174 web175 web176 web177-179 web180-183 web184 web185 web187 web190 web191 web192 web193 web194 web195 web196 web197 web199 web201 web202 web203 web204 web205 web206 web207 web208 web209 web210 web…

vscode调试Unity

文章目录 vscode调试UnityC#环境需求开始调试 Lua添加Debugger环境配置联系.txt文件配置Java环境 添加调试代码断点不生效的问题 vscode调试Unity C# 现在使用vscode调试Unity的C#代码很简单&#xff0c;直接在vscode的EXTENSIONS里面搜索“Unity”&#xff0c;第一个就是&am…

VMware虚拟机更换引导顺序

前言 我用wmware装了黑群晖测试&#xff0c;将img转成vmdisk的格式之后发现系统引导盘之后1G&#xff0c;有点太小了 我准备把wmware的黑群晖系统迁移到新添加的虚拟磁盘里 1.登录黑群晖的SSH 请先在黑群晖的控制面板中的终端机和SNMP里面启用SSH功能&#xff0c;才能使用ss…

PLC_博图系列☞P=:在信号上升沿置位操作数

PLC_博图系列☞P&#xff1a;在信号上升沿置位操作数 文章目录 PLC_博图系列☞P&#xff1a;在信号上升沿置位操作数背景介绍P&#xff1a;在信号上升沿置位操作数说明参数示例 关键字&#xff1a; PLC、 西门子、 博图、 Siemens 、 P 背景介绍 这是一篇关于PLC编程的文章…

DC-5靶机

一.环境搭建 1.下载地址 靶机下载地址&#xff1a;https://download.vulnhub.com/dc/DC-5.zip 2.虚拟机配置 切换nat模式&#xff0c;有问题全选重试和是&#xff0c;打到这了&#xff0c;我感觉这个配置我都不用写了&#xff0c;启动靶机如下图所示即可 二.开始渗透 1.信…

Few-short Learning笔记-1

Few short learning 用很少的样本进行分类或者是回归 support set&#xff1a;小的数据集&#xff08;无法训练出深度神经网络&#xff09; few short learning的目标是让机器自己学会学习。 few shot learning是一种meta learning&#xff08;learn to learn&#xff09; 举…

Rust编程(五)终章:查漏补缺

闭包 & 迭代器 闭包&#xff08;Closure&#xff09;通常是指词法闭包&#xff0c;是一个持有外部环境变量的函数。外部环境是指闭包定义时所在的词法作用域。外部环境变量&#xff0c;在函数式编程范式中也被称为自由变量&#xff0c;是指并不是在闭包内定义的变量。将自…

MySQL学习笔记------DCL

DCL Data Control Language&#xff08;数据控制语言&#xff09;&#xff0c;用来管理数据库用户、控制数据库的访问权限 一、管理用户 1、查询用户 USE mysql&#xff1b; select *from user&#xff1b; 2、创建用户 create user 用户名主机名 identified by 密码&a…

向机器人传授人类社会同步的艺术

在数字时代&#xff0c;社交机器人正迅速成为主流社会的一部分&#xff0c;从培训医生和教育儿童到提供谈话疗法和客户服务。现在&#xff0c;这是一个价值数十亿美元的全球产业&#xff0c;对具有类似人类社交智能的机器人的需求不断增长&#xff0c;这标志着我们技术史上的一…

Linux之冯诺依曼体系,操作系统,进程的理解,进程状态,以及进程的优先级

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 算法 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 目录 一.冯诺依曼体系 二.操作系统 2.1概念 2.2结构示意图&…

主流公链 - BCH BSV BTG

为什么出现分叉 BTC是自由的&#xff0c;BTC社区也是自由的&#xff0c;自然而然的会出现不同观点的群体 1. 比特币现金&#xff08;Bitcoin Cash&#xff0c;BCH&#xff09; 分叉日期&#xff1a; 2017年8月1日主要目的&#xff1a; 提高比特币的交易吞吐量和降低交易费用技术…

写作类AI推荐(一)

本章要介绍的写作AI如下&#xff1a; paperpal 特点&#xff1a; 面向科研人员的AI写作工具。可以选择自己的专业&#xff0c;如本科生/教授。 链接&#xff1a;Paperpal-专业AI论文润色与论文检测平台 笔灵 特点&#xff1a; 面向专业写作领域的AI写作工具。可以选择要写的文章…

人事管理系统|基于springboot人事管理系统的设计与实现(附项目源码+论文)

基于springboot人事管理系统的设计与实现 目录 基于springboot人事管理系统的设计与实现 一、摘要 二、相关技术 三、系统设计 3.1 整体功能结构图 3.2 功能具体细节设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取&#xff1a; 一、摘要 传统信息…

【ripro美化】全站美化包WordPress RiPro主题二开美化版sucaihu-childV1.9(功能集成到后台)

使用介绍 1、【宝塔】删除ripro文件&#xff0c;上传最新ripro版本&#xff0c;然后上传压缩包内的ripro里面的对应文件到ripro主题对应内覆盖&#xff08;找到对应路径单个文件去覆盖&#xff09;。 2、然后上传ripro-chlid子主题美化包到/wp-content/themes路径下 3、注意顺…

npm卸载不掉的解决方案

不管怎么重装重启都报错 真服了&#xff0c;npm卸载不掉绝对是有缓存存在&#xff0c;用where npm查到d盘 实际上根本不在这个地方&#xff0c;这个是我安装的6.14.12版本的npm的地方&#xff0c;我说我怎么怎么重装怎么导包都不行呢&#xff0c;偷偷隐藏在这个目录里面&#…

GRE_MGRE综合实验

目录 1、R5为ISP&#xff0c;只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址。 IP配置 配置公网全网通 2、&#xff08;1&#xff09;R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方。 PAP认证 &#xff08;2&#xff09;R2与R5之间使用ppp的CHAP认证&am…

如何修改IDEA的代码样式配置+代码格式化快捷键配置

目录 问题现象&#xff1a; 问题分析&#xff1a; 温馨提示&#xff1a; 1、IDEA的代码样式配置 1.1、Use tab character - Smart tabs 配置&#xff1a; 1.2、Tab Size 配置&#xff1a; 1.3、Indent 配置&#xff1a; 1.4、Continuation Indent 配置 1.5、应用并保存 2、…

openstack 不能调度到某主机上分析

dashboard显示有足够资源创建虚拟机 创建一个1c2g20g配置的虚拟机&#xff0c;在过滤时把10-197-0-2这个主机过滤掉了&#xff0c;日志如下&#xff1a; 2024-03-25 17:52:14.087 26 DEBUG nova.scheduler.filters.disk_filter [req-8f2f32fb-1efe-4e5d-81fc-618210c7c76d 773…

【LeetCode: 面试题 16.05. 阶乘尾数 + 阶乘】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

俄罗斯深陷芯片自主困境,良率仅5成 |百能云芯

俄罗斯的芯片产业一直以来都面临着诸多挑战&#xff0c;尤其是在当前的国际形势下&#xff0c;这些挑战更加凸显。随着俄乌冲突的爆发&#xff0c;西方国家对俄罗斯实施了一系列经济制裁&#xff0c;导致俄罗斯科技产业受到了严重影响。据了解&#xff0c;俄国最大的本土芯片厂…