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

自定义fmt::formatter处理非const参数的编译链接错误解决

问题:fmt格式化非const引用对象时出现链接错误

你定义了如下类和fmt格式化器:

class MyClass{
   public:
   std::string _cachedString;
   std::string_view get_string(){
      _cachedString = "abc";
      return _cachedString;
   }
};

template<>
class fmt::formatter<MyClass>{
    public:
    template<typename ParseContext>
    constexpr auto parse(ParseContext& ctx){return ctx.begin();}

    template <typename FormatContext>
    constexpr auto format( MyClass& t, FormatContext& ctx){
        return format_to(ctx.out(), "({})", t.get_string());
    }
};

编译时触发链接错误:

undefined reference to `fmt::v8::detail::value<fmt::v8::basic_format_context<fmt::v8::appender, char> >::value(fmt::v8::detail::unformattable_const)'

问题根源是fmt库默认会尝试以const MyClass&类型匹配格式化器,但你的format函数仅接受非const的MyClass&,导致找不到对应的格式化重载,进而触发未定义符号错误。


解决方案

1. 同时提供const与非const版本的format函数

如果你的类需要同时支持const场景和可修改场景,直接重载format函数即可:

template<>
class fmt::formatter<MyClass>{
    public:
    template<typename ParseContext>
    constexpr auto parse(ParseContext& ctx){return ctx.begin();}

    // 处理非const对象,允许修改内部状态
    template <typename FormatContext>
    auto format(MyClass& t, FormatContext& ctx){
        return format_to(ctx.out(), "({})", t.get_string());
    }

    // 处理const对象的格式化逻辑(按需实现)
    template <typename FormatContext>
    auto format(const MyClass& t, FormatContext& ctx){
        return format_to(ctx.out(), "({})", t._cachedString);
    }
};

2. 显式指定非const引用格式化

如果只需要格式化非const对象,调用fmt::format时确保传递的是非const引用,同时保证格式化器的签名能被正确匹配。注意检查fmt版本兼容性,确保自定义格式化器的写法符合当前版本要求。

3. 拆分修改与格式化逻辑

若允许调整流程,可以先调用修改对象的方法,再用const引用进行格式化:

MyClass obj;
obj.get_string(); // 先完成对象修改
fmt::format("{}", static_cast<const MyClass&>(obj)); // 使用const引用格式化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:31:12