nlohmann::json 支持点号路径或链式 operator[] 直接访问嵌套对象,无需手动递归遍历;推荐用 contains() 或 at() 校验键存在性,避免 out_of_range 异常;json::object_t 与 std::map 不兼容,应保持 json 类型处理,仅叶子节点显式转换;中文、空格、特殊字符键名必须用 ["key"] 访问;数组需先 is_array() 判断再操作。

用 nlohmann::json 直接访问嵌套对象,别手动递归遍历
多数人一看到“嵌套 JSON 转 Map 嵌套”就想着写递归函数一层层 for 遍历,其实 nlohmann::json 本身已支持用点号路径或链式 operator[] 访问任意深度的子对象,根本不需要自己解析结构。
比如 {"user":{"profile":{"name":"Alice","age":30}}},直接写 j["user"]["profile"]["name"] 就能取到值,类型自动推导为 std::string;j["user"]["profile"] 的类型就是 json,可继续当对象用。
- 若某层键不存在,
operator[]返回空json对象(不是nullptr),调用.is_null()或.is_object()判断更安全 - 避免写
j["a"]["b"]["c"].get<:string>()</:string>这种链式调用——中间任一层为空会抛out_of_range异常 - 推荐先用
at()替代[]做存在性校验:if (j.contains("user") && j["user"].contains("profile")) { ... }
std::map 套 std::map 无法直接接收 JSON,得用 json::object_t
nlohmann::json 内部用的是 json::object_t(即 std::map<:string json></:string>),它和裸 std::map<:string std::map std::string>></:string> 不兼容。硬转会导致类型擦除、丢失嵌套结构,甚至编译失败。
正确做法是:把整个 JSON 对象当作 json 类型处理,仅在真正需要提取纯 std::map 时才显式转换最内层叶子节点。
立即学习“C++免费学习笔记(深入)”;
- 叶子值(字符串/数字/布尔)可用
.get<:string>()</:string>、.get<int>()</int>等提取 - 对象节点不要强转成
std::map,保持为json更灵活;如必须转,用auto m = j["x"].get<:object_t>()</:object_t>,但注意这会拷贝全部键值对 -
json::object_t的迭代方式和std::map一致:for (const auto& [k, v] : obj),v类型仍是json
遇到数组嵌套时,json::array_t 和 std::vector 的对应关系要理清
JSON 中的 [{"id":1},{"id":2}] 是数组套对象,不是 Map 嵌套,但常被误当成“嵌套结构”处理。这时候不能指望 std::map 接收,得用 json::array_t 或 std::vector<json></json>。
-
j["list"].is_array()必须先判断,再用j["list"].size()和j["list"][i]访问元素 - 数组内每个元素仍可能是对象,所以
j["list"][0]["id"].get<int>()</int>是合法且高效的 - 若想把整个数组转成
std::vector<:map std::string>></:map>,需逐项提取:先get<:array_t>()</:array_t>,再对每个json元素调用.get<:object_t>()</:object_t>,最后对每个object_t的 value 调用.get<:string>()</:string> - 这种多层转换容易漏判类型,建议只在必要输出环节做,中间过程全用
json
中文键名、空格、特殊字符在 operator[] 中要加引号,不能当标识符用
JSON 键名是字符串,不是 C++ 标识符。像 {"用户信息": {"姓名": "张三"}} 这种,不能写 j.用户信息.姓名,必须用方括号加字符串字面量。
- 正确写法:
j["用户信息"]["姓名"].get<:string>()</:string> - 错误写法:
j.用户信息.姓名(编译不过)、j[用户信息]["姓名"](用户信息被当变量名,未定义) - 键名含空格或横线(如
"first-name")也一样,必须用["first-name"],不能用点号 - 如果键名来自变量,直接用
j[key_str]["inner"],key_str是std::string即可
嵌套深了容易漏掉某层的类型检查,尤其当上游数据不规范时;json 库不会帮你自动降级或补默认值,空字段、null 字段、类型错位都得自己兜底。


















