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.hqwc.cn/news/578081.html

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

相关文章

与鲸同行,智领未来!和鲸科技“人工智能+X”学科建设合作交流会(北京站)圆满结束!

在国家加快发展新质生产力的大背景下&#xff0c;3月25日下午&#xff0c;和鲸科技 2024 年“人工智能X”学科建设合作交流会&#xff08;北京站&#xff09;暨“AIX”实验室建设与供应商选型座谈会顺利召开。为提供更为集中和专业的讨论环境&#xff0c;本次会议特别采取闭门审…

海豚【货运系统源码】货运小程序【用户端+司机端app】源码物流系统搬家系统源码师傅接单

技术栈&#xff1a;前端uniapp后端vuethinkphp 主要功能&#xff1a; 不通车型配置不通价格参数 多城市定位服务 支持发货地 途径地 目的地智能费用计算 支持日期时间 预约下单 支持添加跟单人数选择 支持下单优惠券抵扣 支持司机收藏订单评价 支持订单状态消息通知 支…

抢先一步,搞定阿里面试难题——双亲委派机制揭秘!

希望本文对你有所帮助,欢迎继续关注我的公众号“知其然亦知其所以然”,一起探索更多有趣的技术话题! 大家好,我是小米,欢迎来到我的微信公众号!今天,我们将深入探讨一道备受关注的面试题目——“双亲委派机制”。这个话题是阿里巴巴等顶尖科技公司面试中常常涉及的一环…

企业数据资产管理的战略价值与实施策略

一、引言 数据资产不仅记录了企业的历史运营情况&#xff0c;更能够揭示市场的未来趋势&#xff0c;为企业的决策提供有力支持。因此&#xff0c;如何有效地管理和利用数据资产&#xff0c;已经成为企业竞争力的重要体现。本文将探讨企业数据资产管理的战略价值与实施策略&…

使用uni-app开发微信小程序并实现页面间的跳转

一、下载需要的开发工具 HBuilderX 微信开发者工具 HBuilderX HBuilderX-高效极客技巧 (dcloud.io) 微信开发者工具 下载 / 开发版更新日志 (qq.com) 二、新建项目 通过vue-cli命令行创建项目 参考&#xff1a; uni-app官网 (dcloud.net.cn) 2.1全局安装 vue-cli npm i…

KUKA机器人新控制柜KRC5控制柜的特点

KUKA机器人的新控制柜KRC5控制柜已经上市一段时间了&#xff0c;相比于KRC4控制柜&#xff0c;具有一系列显著的特点&#xff1a; 1、节省空间&#xff1a;KRC5的设计紧凑&#xff0c;有效节约工作空间。 2、高品质和低能耗&#xff1a;该产品提供杰出的性能&#xff0c;运行期…

力扣热门算法题 169. 多数元素,200. 岛屿数量,199. 二叉树的右视图

169. 多数元素&#xff0c;200. 岛屿数量&#xff0c;199. 二叉树的右视图&#xff0c;每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.29 可通过leetcode所有测试用例。 目录 169. 多数元素 解题思路 完整代码 Python Java 169. 多数…

【数字孪生平台】使用 Three.js 以 3D 形式可视化日本新宿站地图

在本文中&#xff0c;我们将使用日本新宿站的室内地图数据&#xff0c;并使用 Three.js 将其进行 3D 可视化。更多精彩内容尽在数字孪生平台。 使用的数据 这次&#xff0c;我们将使用日本空间信息中心发布的“新宿站室内地图开放数据”的集成版本&#xff08;ShapeFile&#…

使用CRXjs、Vite、Vue 开发 Chrome 多页面插件,手动配置 vite.config.ts 和 manifest.json 文件

一、使用CRXjs、Vite、Vue 开发 Chrome 多页面插件&#xff0c;手动配置 vite.config.ts 和 manifest.json 文件 一、创建 Vue 项目 1. 使用 Vite 创建 Vue 项目 npm create vitelatest # npm yarn create vite # yarn pnpm create vite # pnpm选择 Vue 和 TS 进入项目…

Node.js v20.12.0 (LTS) 发布,带来这些主要功能!

Node.js 20.12.0&#xff08;LTS&#xff09;发布&#xff0c;看其版本号属于一个重大更新了&#xff0c;这些功能是基于 21.7.1 版本。 曾介绍过的主要功能 新增 crypto.hash() 方法加载和解析环境变量&#xff1a; process.loadEnvFile(path) path 参数可选&#xff0c;默认从…

Unity类银河恶魔城学习记录11-8 p110 Enemy modifiers源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili EnemyStat.cs using System.Collections; using System.Collections.Gener…

Midjourney绘图欣赏系列(十四)

Midjourney介绍 Midjourney 是生成式人工智能的一个很好的例子&#xff0c;它根据文本提示创建图像。它与 Dall-E 和 Stable Diffusion 一起成为最流行的 AI 艺术创作工具之一。与竞争对手不同&#xff0c;Midjourney 是自筹资金且闭源的&#xff0c;因此确切了解其幕后内容尚不…