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

跟随Cherno教程开发游戏引擎时SPDLOG格式化器添加问题

问题:SPDLOG自定义格式化器无法生效导致格式化错误

问题背景

跟随Cherno的C++游戏引擎教程开发时,添加GLFW错误处理环节遇到SPDLOG格式化报错,提示无法格式化某类型,尝试为Pluton::Event添加自定义格式化器后问题仍未解决。


相关代码片段

日志宏定义(Log.h)

#define PL_CORE_TRACE(...)      ::Pluton::Log::GetCoreLogger()->trace(__VA_ARGS__)
#define PL_CORE_WARN(...)       ::Pluton::Log::GetCoreLogger()->warn(__VA_ARGS__)
#define PL_CORE_INFO(...)       ::Pluton::Log::GetCoreLogger()->info(__VA_ARGS__)
#define PL_CORE_ERROR(...)      ::Pluton::Log::GetCoreLogger()->error(__VA_ARGS__)
#define PL_CORE_FATAL(...)      ::Pluton::Log::GetCoreLogger()->fatal(__VA_ARGS__)

事件处理代码

void Application::OnEvent(Event& e) {
    PL_CORE_INFO("{0}", e);
}

GLFW错误回调绑定

static void GLFWErrorCallback(int error, const char* description) {
    PL_CORE_ERROR("GLFW Error ({0}): {1}",error,description);
}
// Application::Init()中初始化GLFW的代码片段
if (!s_GLFWInitialized) {
            int success = glfwInit();
            PL_CORE_ASSERT("GLFW NOT INITIALIZED");
            glfwSetErrorCallback(GLFWErrorCallback);
            s_GLFWInitialized = true;
        }

错误信息

Cannot format an argument. To make type T formattable provide a formatter specialization.


已尝试的自定义格式化器(Log.cpp)

struct fmt::formatter<Pluton::Event> {
    constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
        return ctx.end();
    }

    template <typename FormatContext>
    auto format(const Pluton::Event& input, FormatContext& ctx) -> decltype(ctx.out()) {
        return format_to(ctx.out(),
            "(Name:{})",
            input.GetName() {});
    }

};

解决方案

  1. 修复格式化器语法错误
    自定义格式化器中input.GetName() {}多了一对冗余大括号,修正后代码:

    struct fmt::formatter<Pluton::Event> {
        constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
            return ctx.end();
        }
    
        template <typename FormatContext>
        auto format(const Pluton::Event& input, FormatContext& ctx) -> decltype(ctx.out()) {
            return format_to(ctx.out(), "(Name:{})", input.GetName());
        }
    };
    
  2. 确保格式化器全局可见

    • fmt::formatter特化必须在fmt命名空间下定义,且要保证在所有使用Event格式化的代码(比如Application.cpp)编译前,该特化已经被包含。
    • 建议将格式化器定义移至Event.h或专门的EventFormatter.h中,在所有用到Event日志输出的文件中引入该头文件,而非仅放在Log.cpp里。
  3. 排查断言宏的潜在问题
    当前PL_CORE_ASSERT("GLFW NOT INITIALIZED")写法不符合常规断言逻辑,正确写法应为PL_CORE_ASSERT(success, "GLFW NOT INITIALIZED")。若断言宏内部使用了日志格式化,错误的参数传递也可能触发该报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 16:01:09