如何用宏或模板元编程生成枚举及索引获取函数?
用C++预处理器宏生成枚举索引Getter函数
需求背景
需要定义如下枚举类,其值为1按索引左移的结果:
enum class MyEnum { MyEnum1 = 0x0001, MyEnum2 = 0x0002, MyEnum3 = 0x0004, MyEnum4 = 0x0008, MyEnum5 = 0x0010 };
为避免新增枚举项时出现拼写错误,希望通过枚举名称的字符串数组,自动生成对应Getter函数(如getMyEnum1()返回0,getMyEnum2()返回1等),可以借助预处理器的##连接符实现。
实现方案
预处理器无法直接遍历已定义的数组,更合理的方式是先维护枚举项的源列表,再通过宏批量生成枚举类、名称数组和Getter函数,全程避免重复编写内容。
步骤1:定义枚举项列表
先集中列出所有枚举项的名称和对应索引:
#define MY_ENUM_ENTRIES \ ENTRY(MyEnum1, 0) \ ENTRY(MyEnum2, 1) \ ENTRY(MyEnum3, 2) \ ENTRY(MyEnum4, 3) \ ENTRY(MyEnum5, 4)
步骤2:生成枚举类
通过重定义ENTRY宏,展开成枚举成员:
// 展开为枚举成员定义 #define ENTRY(NAME, INDEX) NAME = (1 << INDEX), enum class MyEnum { MY_ENUM_ENTRIES }; #undef ENTRY // 清除当前ENTRY宏定义,避免冲突
步骤3:生成枚举名称数组
再次重定义ENTRY宏,展开成字符串元素:
// 展开为字符串数组元素 #define ENTRY(NAME, INDEX) #NAME, constexpr std::array<const char*, 5> MyEnumNames = { MY_ENUM_ENTRIES }; #undef ENTRY
步骤4:生成Getter函数
最后一次重定义ENTRY宏,利用##连接符生成Getter函数:
// 展开为Getter函数,##用于拼接函数名 #define ENTRY(NAME, INDEX) constexpr int get##NAME() { return INDEX; } MY_ENUM_ENTRIES #undef ENTRY
效果说明
完成上述定义后,会自动生成:
- 符合要求的
MyEnum枚举类,每个成员值为1 << 索引 - 包含所有枚举名称的
MyEnumNames数组 - 对应的Getter函数:
getMyEnum1()返回0,getMyEnum2()返回1,以此类推
后续新增枚举项时,只需在MY_ENUM_ENTRIES中添加一行ENTRY(新名称, 新索引),所有相关代码会自动更新,彻底避免拼写错误。
内容的提问来源于stack exchange,提问作者window_handle
相关产品推荐
相关产品推荐

