存储可无显式转换用于switch的固定长度命名常量的最优数据结构是什么
问题解答
你现有写法在C20及更高版本中本身是合法的,无法编译大概率是没有开启编译器的C20标准支持:using enum就是C++20专门引入用来简化enum class使用冗余问题的语法,加了该声明后switch的case里可以直接用枚举名,不需要额外转换。
如果使用的是C11/14/17版本,无法使用C20特性,可参考以下符合你所有选择标准的方案:
方案1:作用域封装普通枚举(最推荐)
普通枚举的底层值可以直接和整数比较,不需要类型转换,封装在独立作用域中也不会造成命名空间污染:
// 封装在专属命名空间,避免全局命名污染 namespace EventType { enum : uint8_t { NOTE_ON = 9, NOTE_OFF = 8, CONTROL_CHANGE = 11, CHANNEL_PRESSURE = 13, PITCH_WHEEL_CHANGE = 14 }; } // 局部使用时可以直接导入命名空间,代码完全无冗余 using namespace EventType; switch(((Status & 0xF0)>>4)){ case NOTE_OFF: std::cout << "NOTE OFF: " << std::endl; break; case NOTE_ON: std::cout << "NOTE ON: " << std::endl; break; case CONTROL_CHANGE: std::cout << "CONTROL CHANGE: " <<std::endl; break; case CHANNEL_PRESSURE: std::cout << "CHANNEL PRESSURE: " <<std::endl; break; case PITCH_WHEEL_CHANGE: std::cout << "PITCH WHEEL CHANGE: " << std::endl; break; default: std::cout << "UNKNOWN EVENT TYPE: " << std::endl; }
该方案完全符合你提出的所有要求:
- 所有值编译期确定,运行期不可修改
- 封装在专属命名空间中,无命名空间污染
- 不需要显式转换、不需要调用成员函数,代码简洁
- 完全适配switch case、if判断等使用场景
方案2:保留enum class的强类型特性的简化写法
如果你希望保留enum class的强类型检查能力,不想退化为普通枚举,可以只在switch条件处做一次统一转换,不需要每个case单独转:
enum class EventType : uint8_t{ NOTE_ON = 9, NOTE_OFF = 8, CONTROL_CHANGE = 11, CHANNEL_PRESSURE = 13, PITCH_WHEEL_CHANGE = 14 }; // 自定义编译期转换函数,C++23可直接用标准库的std::to_underlying constexpr uint8_t to_underlying(EventType e) noexcept { return static_cast<uint8_t>(e); } // 使用时仅在switch条件处转换一次即可 switch(static_cast<EventType>((Status & 0xF0)>>4)){ case EventType::NOTE_OFF: std::cout << "NOTE OFF: " << std::endl; break; case EventType::NOTE_ON: std::cout << "NOTE ON: " << std::endl; break; // 其余case逻辑相同 }
不建议使用宏定义、全局constexpr变量数组这类方案,要么封装性差容易造成命名冲突,要么没有基础类型检查,不符合你的需求。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

