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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 19:05:28