如何输出enum class枚举值的对应名称,且无需随枚举变更修改输出函数
问题根本原因
你遇到的问题本质是宏的字符串化操作#是在预处理阶段执行,只会对输入的字面标识符做字符串转换,不会处理运行时的变量值。你把枚举值传入函数后,预处理阶段看到的宏参数就是a这个变量名,自然只会输出"a"。
最优解决方案
以下方案都可以做到枚举项增减时,只需要修改枚举定义本身,不需要调整转换逻辑:
方案1:X宏(纯标准C++,全版本兼容,无第三方依赖)
X宏是行业内最常用的可维护方案,核心是把枚举项的定义单独抽成一个宏列表,后续的枚举定义、字符串映射表都基于这个列表自动生成:
#include <iostream> #include <type_traits> // 枚举项统一在这里定义,新增/删除只改这一处 #define A_ENUM_LIST \ X(type_a) \ X(type_b) // 新增枚举项直接加一行X(xxx)即可 // 自动生成enum class定义 enum class A { #define X(name) name, A_ENUM_LIST #undef X }; // 自动生成字符串转换函数,不需要手动修改 const char* A_to_str(A val) { static const char* const names[] = { #define X(name) #name, // 如果需要输出带A::前缀的格式,把上面的#name改成"A::"#name即可 A_ENUM_LIST #undef X }; return names[static_cast<std::underlying_type_t<A>>(val)]; } // 封装后的输出函数 void func(A a) { std::cout << A_to_str(a) << std::endl; } int main() { func(A::type_a); // 输出 type_a 或 A::type_a,可自定义 }
如果你的枚举不是从0开始的连续值,可以修改X宏为带枚举值的格式,映射表改用编译期排序的键值对数组做二分查找,依然不需要手动调整转换逻辑。
方案2:C++17+ 第三方库magic_enum(零侵入原有代码)
如果允许引入头文件级的第三方依赖,magic_enum库完全不需要修改原有枚举定义,直接调用即可:
#include <iostream> #include <magic_enum.hpp> // 只需要包含头文件,不需要编译集成 enum class A { type_a, type_b }; void func(A a) { std::cout << magic_enum::enum_name(a) << std::endl; } int main() { func(A::type_a); // 直接输出 type_a }
该方案的优点是完全零侵入原有枚举代码,缺点是需要C++17及以上编译器支持,默认支持的枚举值范围是-128~127(可手动调整配置扩大范围)。
内容的提问来源于stack exchange,提问作者f1msch
相关产品推荐
相关产品推荐

