You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用宏或模板元编程生成枚举及索引获取函数?

用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:15:22