spdlog::level::level_enum与nlohmann::json互转报错,求解决方法
问题:JSON字符串转spdlog日志枚举类型失败?
我参考nlohmann-json的枚举转换教程,尝试将JSON中的log-level值转换为spdlog::level::level_enum类型。
给定JSON:
{ "log-level": "info", "log-path": "/var/log/info/" }
对应的C++代码:
#include "spdlog/spdlog.h" #include "nlohmann/json.hpp" NLOHMANN_JSON_SERIALIZE_ENUM(spdlog::level::level_enum, { {spdlog::level::level_enum::trace, "trace"}, {spdlog::level::level_enum::debug, "debug"}, {spdlog::level::level_enum::info, "info"}, {spdlog::level::level_enum::warn, "warn"}, {spdlog::level::level_enum::err, "err"}, {spdlog::level::level_enum::critical, "critical"}, {spdlog::level::level_enum::off, "off"} }) int main() { std::string input = R"({ "log-level": "info", "log-path": "/var/log/info/" } )"; auto json = nlohmann::json::parse(input); json["log-level"].template get<spdlog::level::level_enum>(); }
运行后抛出错误:
terminate called after throwing an instance of 'nlohmann::json_abi_v3_11_2::detail::type_error' what(): [json.exception.type_error.302] type must be number, but is object
错误原因
问题出在NLOHMANN_JSON_SERIALIZE_ENUM宏的声明顺序上:你在包含nlohmann/json.hpp之后才定义枚举的序列化规则,但nlohmann-json要求这个宏必须在包含json头文件之前声明,否则无法生成正确的序列化/反序列化模板特化。此时库会默认把枚举当作数值类型处理,而JSON中的"info"是字符串,类型不匹配就触发了错误。
解决方案
调整代码顺序,先包含spdlog头文件(确保spdlog::level::level_enum可见),然后声明枚举序列化宏,最后包含nlohmann/json头文件:
#include "spdlog/spdlog.h" // 先声明枚举与字符串的映射规则 NLOHMANN_JSON_SERIALIZE_ENUM(spdlog::level::level_enum, { {spdlog::level::level_enum::trace, "trace"}, {spdlog::level::level_enum::debug, "debug"}, {spdlog::level::level_enum::info, "info"}, {spdlog::level::level_enum::warn, "warn"}, {spdlog::level::level_enum::err, "err"}, {spdlog::level::level_enum::critical, "critical"}, {spdlog::level::level_enum::off, "off"} }) // 再包含json头文件 #include "nlohmann/json.hpp" int main() { std::string input = R"({ "log-level": "info", "log-path": "/var/log/info/" } )"; auto json = nlohmann::json::parse(input); // 正常转换枚举类型 auto log_level = json["log-level"].get<spdlog::level::level_enum>(); }
你也可以使用get_to方法来简化转换代码:
spdlog::level::level_enum log_level; json["log-level"].get_to(log_level);
内容的提问来源于stack exchange,提问作者user22343737
相关产品推荐
相关产品推荐

