C++20中如何让std::format兼容枚举类?无需额外代码方案问询
解决方案
要让make_str无需额外代码兼容所有枚举类,核心是给所有枚举类型提供通用的std::formatter特化,让std::vformat自动将枚举转换为其底层整数类型处理。
C++20允许我们通过模板特化,针对std::is_enum_v为true的类型,复用底层整数类型的formatter逻辑:
#include <format> #include <string> #include <type_traits> // 原有的make_str模板函数 template<typename... Args> std::string make_str(std::string_view fmt, Args&&... args) { return std::vformat(fmt, std::make_format_args(std::forward<Args>(args)...)); } // 通用枚举类formatter特化 template<typename Enum> requires std::is_enum_v<Enum> struct std::formatter<Enum> : std::formatter<std::underlying_type_t<Enum>> { template<typename FormatContext> auto format(Enum e, FormatContext& ctx) const { return std::formatter<std::underlying_type_t<Enum>>::format( static_cast<std::underlying_type_t<Enum>>(e), ctx); } }; // 测试用枚举类 enum class wing { left, right, both }; int main() { // 现在可以直接格式化枚举类了 std::string s = make_str("Wing: {}", wing::left); // s的值是 "Wing: 0" return 0; }
原理说明
- 利用C++20的
requires约束,这个特化只会作用于枚举类型(包括enum class和普通enum)。 - 特化的
formatter继承自枚举底层类型的formatter,直接把枚举值强转成底层整数后复用已有格式化逻辑,支持所有整数格式化选项(比如十六进制、宽度对齐等)。 - 这个特化只需要写一次,就能自动适配项目中所有枚举类,无需逐个修改或添加代码。
注意事项
- 如果后续需要某些枚举类支持自定义字符串格式化(比如把
wing::left输出成"left"而不是0),可以针对特定枚举类单独特化std::formatter,编译器会优先匹配更具体的特化版本。 - 该方案依赖C20的概念(
requires)和std::underlying_type_t,符合你的C20环境要求。
内容的提问来源于stack exchange,提问作者user14530855
相关产品推荐
相关产品推荐

