不能直接用 std::map 遍历重命名 key,因 nlohmann/json 中 key 是 const string_view,不可赋值,且遍历时修改会致迭代器失效;应递归重建对象,对 object 的 key 调用下划线转换函数(如 "camelcase"→"camel_case"),其余类型透传。

为什么不能直接用 std::map 遍历后重命名 Key
因为 JSON 解析库(如 nlohmann/json)返回的 json 对象是嵌套结构,Key 不是独立可写字段;直接遍历 json::object_t 并修改 key 名会触发迭代器失效,或根本无法原地修改 —— json 的 key 是 const string_view 类型,不支持赋值。
推荐做法:递归重建对象,而非就地修改
核心思路是深度优先遍历原始 JSON,对每个 object 的 key 做下划线转换(如 "camelCase" → "camel_case"),再构造新 json 对象。需注意:
-
nlohmann::json支持for (auto& [key, value] : j.items())安全遍历,但必须用新对象承接结果 - 下划线转换函数要处理连续大写字母(如
"XMLParser"→"xml_parser"),不能只插下划线 - 数组、字符串、数字、布尔值、null 直接透传,只处理 object 类型
示例转换函数:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
std::string to_snake_case(const std::string& s) {
if (s.empty()) return s;
std::string out;
for (size_t i = 0; i
<h3>完整递归实现要点</h3>
<p>使用 <code>nlohmann::json</code> 时,关键在于区分类型并递归处理:</p>
- 遇到
j.is_object():新建空json,遍历j.items(),对每个key调用to_snake_case(),value 递归调用转换函数 - 遇到
j.is_array():对每个元素递归调用,再用json::array()构造新数组 - 基础类型(string/number/boolean/null)直接返回原值,不做任何改动
- 务必用
json::object_t的构造方式避免隐式拷贝开销,例如:result[to_snake_case(key)] = transform_value(value);
容易被忽略的边界情况
实际数据中常出现这些坑:
- Key 里含数字或特殊字符(如
"user1Name"→"user1_name",不是"user_1_name")——to_snake_case必须只响应大写字母,不拆数字 - 全大写缩写(
"URL"、"ID")应转为"url"、"id",而非"u_r_l";需在转换逻辑中加连写大写检测 - 空对象(
{})或空数组([])必须保留结构,不能变成 null - 如果原始 JSON 含重复转换后的 key(如
"firstName"和"first_name"),后者会覆盖前者 —— 这属于业务冲突,代码层无法自动解决
真正麻烦的从来不是怎么写递归,而是确认你的 snake case 规则是否和下游服务一致 —— 比如要不要保留首尾下划线、如何处理 Unicode 字母,这些得看 API 文档,不是靠 C++ 代码能猜出来的。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










