如何用两个字符为C++ enum class设置constexpr枚举值
双字符消息类型的constexpr枚举类实现方案
你原来的代码编译失败,核心问题是atoi不是编译期函数,std::string也没法在编译时构造,而枚举类的初始化必须是编译期常量。
要实现用双字符定义constexpr枚举,直接拿字符的ASCII值拼字节就行——字符字面量本身就是编译期常量,完全符合要求。
核心实现思路
先搞清楚消息头里双字符的存储顺序:
- 要是消息头是大端序(第一个字符占高字节,第二个占低字节),就用
('A' << 8) | 'R'这种拼接方式 - 要是是小端序,就反过来写成
('R' << 8) | 'A'
假设你的消息头是大端序,直接这么写就行:
#include <cstdint> enum class MsgType : uint16_t { AR = (static_cast<uint16_t>('A') << 8) | static_cast<uint16_t>('R'), PF = (static_cast<uint16_t>('P') << 8) | static_cast<uint16_t>('F') };
正常用在switch里
这样定义的枚举值是正经的编译期常量,完全能在switch里用,编译器还能帮你检查有没有遗漏的枚举分支(开-Wswitch-enum这类警告的话):
void handle_message(MsgType type) { switch (type) { case MsgType::AR: // 处理AR类型的消息 break; case MsgType::PF: // 处理PF类型的消息 break; } }
嫌麻烦?整个辅助函数
如果要定义好多双字符枚举,整个constexpr辅助函数简化代码:
constexpr uint16_t pack_two_chars(char first, char second) { return (static_cast<uint16_t>(first) << 8) | static_cast<uint16_t>(second); } enum class MsgType : uint16_t { AR = pack_two_chars('A', 'R'), PF = pack_two_chars('P', 'F') };
这个函数纯编译期计算,没运行时开销,用着更清爽。
注意点
- 确保字符的字节和消息头完全匹配,要是消息头用的是UTF-8,ASCII字符直接用字面量没问题
- 字节序别搞反,不然枚举值和实际消息头的字段对不上
内容的提问来源于stack exchange,提问作者intrigued_66
相关产品推荐
相关产品推荐

