使用C++11新特性,实现用字符串作为switch的case子句(转)

实战c++中的string系列--将string用于switch语句(c++做C#的事儿, switch中break还是return厉害) 作为一个C++程序员,或是出于习惯,或是出于无奈,你多少次这么写:if (!strcmp(pszValue, "Value X")) DoThis(); else if (!strcmp(pszValue, "Value Y")) DoThat(); else if (!strcmp(pszValue, "Value Z")) DoSomethingElse(); else 阅读详情
转自: http://blog.youkuaiyun.com/yozidream/article/details/22789147
C++的switch没有使用字符串作为case选择分支的。所以这里用这个作为字符串的case分支真的很不错。因为这里用到了C++11的constexpr函数文字常量语法,函数会在编译的时候生成字串符的hash值,所以不会出现case重复的情况,如果出现重复程序会编译报错。
下边是原文:

有时候,我们想写出下面这样的switch语句:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. const char* str = "first";  
  2. switch(str){  
  3. case "first":  
  4.     cout << "1st one" << endl;  
  5.     break;  
  6. case "second":  
  7.     cout << "2nd one" << endl;  
  8.     break;  
  9. case "third":  
  10.     cout << "3rd one" << endl;  
  11.     break;  
  12. default:  
  13.     cout << "Default..." << endl;  
  14. }  

但是在c++中,是不能用字符串来作为case的标签的;于是,很疑惑,我们只能用其他的办法来实现这样的需求。

但幸运的是,c++11引入了constexpr和自定义文字常量,将这两个新特性结合,我们实现出看上去像上面这样的代码。


基本思路为:

1、定义一个hash函数,计算出字符串的hash值,将字符串转换为1个整数;

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. typedef std::uint64_t hash_t;  
  2.    
  3. constexpr hash_t prime = 0x100000001B3ull;  
  4. constexpr hash_t basis = 0xCBF29CE484222325ull;  
  5.   
  6. hash_t hash_(char const* str)  
  7. {  
  8.     hash_t ret{basis};  
  9.    
  10.     while(*str){  
  11.         ret ^= *str;  
  12.         ret *= prime;  
  13.         str++;  
  14.     }  
  15.    
  16.     return ret;  
  17. }  

2、利用c++11自定义文字常量的语法,定义一个constexpr函数,switch的case标签处调用这个constexpr函数。如下

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. constexpr hash_t hash_compile_time(char const* str, hash_t last_value = basis)  
  2. {  
  3.     return *str ? hash_compile_time(str+1, (*str ^ last_value) * prime) : last_value;  
  4. }  


这个函数只有短短的一行,利用递归得到了与上面hash_函数得到的同样值,由于用constexpr声明了函数,因此编译器可以在编译期得出一个字符串的hash值,而这正是关键,既然是编译器就可以得到的整型常量,自然可以放到switch的case标签处了。

于是我们可以写出这样的swich语句:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void simple_switch2(char const* str)  
  2. {  
  3.     using namespace std;  
  4.     switch(hash_(str)){  
  5.     case hash_compile_time("first"):  
  6.         cout << "1st one" << endl;  
  7.         break;  
  8.     case hash_compile_time("second"):  
  9.         cout << "2nd one" << endl;  
  10.         break;  
  11.     case hash_compile_time("third"):  
  12.         cout << "3rd one" << endl;  
  13.         break;  
  14.     default:  
  15.         cout << "Default..." << endl;  
  16.     }  
  17. }  

这个实现中,hash_compile_time("first")是编译器计算出来的一个常量,因此可以用作case标签;而且如果出现了hash值冲突,编译器回给出错误提示。


3、上面的语法还不够漂亮,利用自定义文字常量,重载一个operator如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. constexpr unsigned long long operator "" _hash(char const* p, size_t)  
  2. {  
  3.     return hash_compile_time(p);  
  4. }  

现在我们可以写这样的文字常量,用“_hash”作为自定义文字常量的后缀,编译器看到这个后缀结尾的文字常量,就会去调用我们重载的operator,得到和调用hash_compile_time是一样的值,但看起来舒服多了:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. "first"_hash  


现在,我们写出的switch语句就好看多了。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void simple_switch(char const* str)  
  2. {  
  3.     using namespace std;  
  4.     switch(hash_(str)){  
  5.     case "first"_hash:  
  6.         cout << "1st one" << endl;  
  7.         break;  
  8.     case "second"_hash:  
  9.         cout << "2nd one" << endl;  
  10.         break;  
  11.     case "third"_hash:  
  12.         cout << "3rd one" << endl;  
  13.         break;  
  14.     default:  
  15.         cout << "Default..." << endl;  
  16.     }  
  17. }  
  18.    

全文完。希望我讲清楚了。
经过我的测试,在cocos2d-x 3.2版本里,我对骨骼动画的帧事件中用了switch,可以正常使用。

C++基础(十二):string类 1. string是表示字符串的字符串类,它就是一个自定义类型,可以用它来实例化字符串类对象。2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作成员函数以及描述这个字符串类属性的一些成员变量。3. string在底层实际是:basic_string模板类的别名,typedef basic_string string;4. 不能操作多字节或者变长字符的序列。 阅读详情

相关推荐

C语言switch case语句详解与性能优化

在编程中,多路分支是常见的控制结构需求。传统if-else语句在处理大量离散条件时存在可读性和效率问题。switch case作为结构化编程的重要特性,通过跳转表机制实现高效分支,特别适合处理整型值的多路判断。其核心原理是将表达式值与case常量匹配,直接跳转到对应代码块,避免了if-else的逐级判断。在嵌入式系统和性能敏感场景中,switch case通常比等效if-else快20%-30%。典型应用包括状态机实现、命令解析和菜单处理等。理解case穿透特性和break语句的正确使用是掌握该语法的关键,

weixin_34408624的博客 423

C++ : switch:switch string的两种用法

C++ : 基础点滴:switch string的两种用法

C++ JAVA的专栏 5374

【C++实战篇】 switch 语句case后面可以跟 string变量吗? case后面可以怎么跟 string变量?

如果想在 switch 语句中匹配字符串,可以将字符串转换为整数或者使用其他方法来实现。一种常见的方法是使用 std::unordered_map 或 std::map 来将字符串映射到整数,然后在 switch 语句中使用整数进行匹配。在上述示例中,我们将字符串映射到整数,然后在 switch 语句中使用整数进行匹配。在 C++ 中,case 语句通常是用于 switch 语句中,用来匹配整数或枚举类型的常量。在标准的 C++ 中,,因为 case 语句。不能直接跟字符串变量。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 1840

C++实现switch匹配字符串string(map方法)

//通用的相机设置参数(定义) int SV_FUNC_SetCameraParam(void *handle, const string controlParam, unsigned int input_set_camera_param) { map<string, int>Camera_Control_Param = { {"exposure", 1 }, {"video_gain", 2 }, {"exposure_mode",3}, {"external_tri

手写不期而遇的博客 7523

考试遇到 Assistant API 考点时,该掌握哪些要点?

【摘要】聚焦阿里云大模型 ACP 认证中智能体 Assistant API 考点,我结合自学认证成功经验,分享复习攻略。先解析 assistants、threads 等五个核心组件作用与关系,点明各组件支持及不支持的方法,最后给出计算 Python 代码调用大模型次数的思路,助力考生攻克考点、顺利拿证 。

davidkorhenn的博客 494

潜在图神经网络学习笔记(Latent Graph Neural Networks for Human Skeleton-based Action Recognition)

在本文中,我们从一个新的角度来解决这个问题,通过将非结构化的骨架数据映射到潜在空间,如图2所示,这里称为潜在特征空间或嵌入空间,其中一组项嵌入在一个流形中[ 1 ],并且在潜在空间中彼此更相似的项被放置在彼此更接近的位置。潜在空间中的位置可以被认为是由一组潜在变量定义的,这些潜在变量来源于对象的相似性。将骨架数据嵌入到流形中,消除了远近邻居之间的冗余依赖关系,以解决加权问题。得到具有多尺度聚合特征的稀疏图矩阵结构,以更好地理解骨骼关节的直接加权信息。

qq_45631885的博客 488

使用C++11新特性,实现用字符串作为switch的case子句

用字符串作为的c++ switch的case标签。

夸父逐日 2万+

Sony微单相机alpha6000 wifi远程控制(1)

引言 Sony’s Camera Remote API beta SDK allows you to control a number of Sony cameras, including Sony Action cams, Sony Alpha cameras and Lens Style cameras, wirelessly from another device. 索尼于2017年三月Re...

markfuk996的博客 4964

C++ switch case 匹配字符串

有时候,我们想写出下面这样的switch语句: const char* str = "first"; switch(str){ case "first": cout << "1st one" << endl; break; case "second": cout << "2nd one" << en...

weixin_37815019的博客 3741

【实战指南】Green Hills MULTI-IDE 从零安装到工程创建全流程

本文详细介绍了Green Hills MULTI-IDE从零安装到工程创建的全流程,包括系统要求检查、安装步骤、工程配置及调试技巧。特别适合嵌入式开发新手快速上手这款专业IDE工具,提升开发效率。

weixin_28740299的博客 474

医药领域知识图谱快速及医药问答项目(项目全过程)

该项目是中科院软件所刘焕勇老师在github上的开源项目,基于知识图谱的医药领域问答项目 Github项目地址:mirrors / liuhuanyong / qasystemonmedicalkg · GitCode 一、项目环境搭建 该部分要十分注意,由于版本升级的问题,一些用法及格式已经不兼容了。 python3.8 下载地址:Python Release Python 3.8.10 | Python.orght...

qq_52062182的博客 9914

C++11新特性,实现用字符串作为switch的case子句

有时候,我们想写出下面这样的switch语句: const char* str = "first";  switch(str){  case "first":      cout "1st one" << endl;      break;  case "second":      cout "2nd

veson258的专栏 4675

基于物联网的门禁与考勤系统(阿里云)_81

本课题设计的基于物联网的门禁与考勤管理系统,结合现代信息技术,利用指纹识别、射频卡、密码输入和远程控制等多种开锁方式,提升门禁系统的安全性和灵活性;同时,通过物联网平台进行数据上传和远程管理,极大提高了管理效率。通过智能化的考勤功能,系统可以实时记录员工的出入情况,并通过云平台进行远程查询和管理,推动门禁与考勤管理的数字化、智能化和高效化。

1万+

[C++]用字符串作为switch的case子句

有一天突发奇想在switch用字符串,遂在网上查找一番,下面代码都是抄的,个人测试一下没目前还没发现问题 原文链接:https://blog.youkuaiyun.com/yozidream/article/details/22789147 实现 1、定义一个hash函数,计算出字符串的hash值,将字符串转换为1个整数; typedef std::uint64_t hash_t; constexpr hash_t prime = 0x100000001B3ull; constexpr hash_t basis

r250414958的博客 866

AE-扭曲-变形-弧

一些AE效果的着色器实现记录

What_can_you_do的博客 1172

基于STM32设计的猪舍养殖的监控系统_325

本课题基于STM32单片机,设计一款能够实时监测猪舍环境的智能监控系统。该系统能够通过温湿度、空气质量、光照强度等传感器实时监测猪舍的环境,并能够通过自动化控制设备(如风扇、照明灯、消毒喷雾等)调节环境参数,确保养殖环境的适宜性。同时,系统还支持通过ESP8266模块实现数据上传与远程控制,使养殖管理者能够通过手机APP或计算机远程监控和控制猪舍环境。

408

C++ switch case 匹配字符串(全网最简单)

switch case 只识别整数和枚举类型,计算机的汉字是从Unicode编码成UTF-8的,Unicode是十六进制数表示,嗯好像可以实现。 需要用到 C++ 11 中 constexpr (常量表达式) 因为 case 之后要求的必须是常量,C++ 11正好提供的有 constexpr 编译期计算出的值作为常量使用。

蓝色风暴的博客 3万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

为C++添加短字符串的switch-case支持

介绍 这篇文章描述了一种在C++中对短字符串(长度为4以内)进行switch-case操作的尝试,如同整型值那样,以此避免因字符串匹配带来的开销,稍微提高运行效率。 背景 如大家所知,C++并不支持对字符串(单字符还是支持的)做switch case的分支操作,因为switch的表达式只支持整型值或可转化为整型值的类型。既然switch case不能用了,那可选的方案就只剩下if-else、

hebezai的专栏 6506

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

c++ switch/case 使用 string的方法

原文:http://blog.youkuaiyun.com/yozidream/article/details/22789147 有时候,我们想写出下面这样的switch语句: [cpp] view plaincopy const char* str = "first";   switch(str){   case "first":       

山寨步兵的专栏 7万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

(一)     实现用字符串作为switch的case子句

1. 问题:实现用字符串作为switch语句的case子句。形如:int main(int argc, const char** argv){ const char* strInput = argv[1]; switch(strInput){ case "first": ...

weixin_33834137的博客 1165

C++ switch case识别字符串数据问题

这段代码中,switch判断的是字符数据,这本来是不被编译器允许的,因为switch case 只识别整数和枚举类型,中文是从Unicode编码成UTF-8的,Unicode是十六进制数表示。因为 case 之后要求的必须是常量,C++ 11正好提供的有 constexpr 编译期计算出的值作为常量使用。所以我们设计了两个函数来将字符数据转换为整数数据。而其中U函数在编译期就会执行。所以这样就可以用switch case来判断字符数据了。这时候需要用到 C++ 11 中 constexpr (常量表达式)

weixin_40462276的博客 1328

android studio 错误: 常量字符串过长_源码|C++ switch case 匹配字符串(全网最简单)

点击关注了解更多精彩内容!!C++ switch case 匹配字符串(全网最简单)我们会遇到这样一个问题:如果有很多字符串,我们要把它们区分开来,我们可以用 if ......elseif ......else...

weixin_31720623的博客 314

C++中实现字符串switch的多种方案:从map到编译期哈希

在编程中,多路分支是控制流的基础概念,通常使用switch语句处理整型或枚举类型的条件判断。其底层原理基于编译器生成的跳转表或二分查找,以实现O(1)或O(log n)的高效执行。然而,C++的语法标准规定switch的条件表达式必须是整型或枚举类型,这源于其追求极致运行时效率和编译期确定性的设计哲学。因此,直接使用std::string对象作为case标签会导致编译错误,因为字符串内容在运行时才能确定,且其等值比较涉及O(n)的复杂度,无法满足编译期常量表达式的要求。这一限制在需要根据字符串内容进行分发的

hideto 420

【C++ 硬核】拒绝 strcmp:在嵌入式中实现 O(1) 的“字符串 Switch-Case” (编译期哈希)

C++11 允许我们自定义后缀。我们可以定义一个_hash后缀,让直接变成一个整数。// 定义字面量操作符通过 C++ 的 constexpr和字面量重载,我们成功地将高级语言的“字符串 Switch”特性带入了嵌入式 C++。代码优雅:可读性极高,像脚本语言一样处理字符串。极致性能:将 O(N) 的字符串匹配变成了 O(1) 的整数跳转。零存储:Flash 里不需要存"AT+RST"这些字符串常量了,只存整数 ID。这,就是 Modern C++ 给嵌入式开发带来的“降维打击”。

Max_uuc的博客 1198

C++使用模板类实现任意类型switch和变量case

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34259559的博客 1017
上一篇: dota2模型导入到3dsmax(转)
下一篇: 游戏中分层状态机的实现(转)
woodcol
博客等级 码龄19年 288粉丝 429原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值