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

如何让枚举类满足C++23的std::formattable概念?

C++23 std::formattable 适配问题解决

问题

从C20切换到C23时,发现原本适配自定义formattable概念的枚举类无法满足std::formattable。示例代码中,自定义formattable<RandomEnum>为真,但std::formattable<RandomEnum, char>为假,导致无法使用std::formattable约束的函数。

原因

你的std::formatter<RandomEnum>的format函数参数固定为std::format_context&,但std::formattable概念会用**不同迭代器类型的std::basic_format_context**做校验(比如MSVC的std::basic_format_context<std::_Phony_fmt_iter_for<char>,char>、Clang的std::basic_format_context<std::back_insert_iterator<std::basic_string<char>>, char>)。

std::format_context是std::basic_format_context的特定迭代器特化,不同迭代器的basic_format_context属于完全不同的类型,无法绑定到固定的std::format_context&参数上,因此std::formattable校验失败。而你之前的C20自定义formattable仅用std::format_context做检查,所以能通过,但不符合C23标准的要求。

解决办法

修改formatter的format函数,使其接受任意类型的basic_format_context:

方案1:模板化FormatContext

#include <format>
#include <string>

enum class RandomEnum { A, B };

template <>
struct std::formatter<RandomEnum> : std::formatter<std::string> {
    template <typename FormatContext>
    auto format(const RandomEnum, FormatContext& ctx) const {
        return std::formatter<std::string>::format("ABC", ctx);
    }
};

int fun(std::formattable<char> auto x) { return 0; }

int main() { return fun(RandomEnum::A); }

方案2:显式指定字符类型并使用basic_format_context

#include <format>
#include <string>

enum class RandomEnum { A, B };

template <>
struct std::formatter<RandomEnum, char> : std::formatter<std::string, char> {
    template <typename OutputIt>
    auto format(const RandomEnum, std::basic_format_context<OutputIt, char>& ctx) const {
        return std::formatter<std::string, char>::format("ABC", ctx);
    }
};

int fun(std::formattable<char> auto x) { return 0; }

int main() { return fun(RandomEnum::A); }

修改后,std::formattable<RandomEnum, char>会正确返回true,代码可通过MSVC和Clang编译。

内容的提问来源于stack exchange,提问作者bers

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:07:32