跟随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() {}); } };
解决方案
修复格式化器语法错误
自定义格式化器中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()); } };确保格式化器全局可见
fmt::formatter特化必须在fmt命名空间下定义,且要保证在所有使用Event格式化的代码(比如Application.cpp)编译前,该特化已经被包含。- 建议将格式化器定义移至
Event.h或专门的EventFormatter.h中,在所有用到Event日志输出的文件中引入该头文件,而非仅放在Log.cpp里。
排查断言宏的潜在问题
当前PL_CORE_ASSERT("GLFW NOT INITIALIZED")写法不符合常规断言逻辑,正确写法应为PL_CORE_ASSERT(success, "GLFW NOT INITIALIZED")。若断言宏内部使用了日志格式化,错误的参数传递也可能触发该报错。
内容的提问来源于stack exchange,提问作者user19926715
相关产品推荐
相关产品推荐

