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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 00:32:33