应使用nlohmann/json等成熟库而非手动拼接:它支持std::vector等STL容器自动转JSON,自定义struct需显式定义to_json/from_json函数,注意键顺序、性能优化及字段校验。
std::vector
转 JSON 时别直接用 std::to_string
直接循环拼接
得到的字符串不是合法 JSON:缺方括号、逗号分隔不规范、没有引号包裹(对字符串类型而言)。JSON 是结构化文本格式,不是简单拼接。
正确做法是使用成熟序列化库处理容器边界和类型差异。推荐优先考虑
(头文件仅需
),它对 STL 容器有原生支持:
构造函数重载了对
、
、
等的隐式转换
嵌套容器也自动递归处理:
→ JSON 数组含多个对象
若用
可加缩进,便于调试;生产环境建议用
(无空格)减小体积
自定义 struct 序列化必须显式定义 to_
js
on/from_
json
STL 容器能自动转 JSON,但你的自定义结构体不行——编译器不知道字段名和顺序。不写序列化函数会报错:
。
必须在命名空间内提供两个自由函数(不能是成员函数):
C知道
CSDN推出的一款AI技术问答工具
下载
立即学习
“
C++免费学习笔记(深入)
”;
字段名必须与 JSON 键名严格一致,大小写敏感
用
而非
:前者抛异常(可捕获),后者静默返回 null 值,容易掩盖字段缺失问题
如果结构体含
,无需额外操作——只要
支持序列化,外层容器就能自动处理
std::map 和 std::unordered_map 行为不同
序列化后键名默认按字典序排列;
则保持插入顺序(nlohmann/json v3.11+ 默认行为),但该顺序不保证跨平台或跨版本一致。
若 JSON 消费方依赖键顺序(如前端展示顺序),应改用
或手动转为
控制顺序
的哈希随机化可能影响测试稳定性,CI 中偶发失败常源于此
所有键类型必须是
(或能隐式转为
);用
当 key 会编译失败
性能敏感场景慎用 operator= 直接赋值
对大容器(如百万级
),写
会触发完整拷贝。实际只需视图式序列化时,可用
配合 reserve + emplace_back 避免中间分配:
减少内部 vector 重分配次数,对大数组提升明显
若容器元素是复杂对象,确保其
函数高效(例如避免深拷贝内部缓存)
调试时用
/
校验类型,比字符串匹配更可靠
nlohmann/json 的自动容器适配很省心,但一旦涉及自定义类型或性能边界,隐式行为就变成黑盒。最容易被忽略的是
中用
还是
——线上服务里一个未检查的缺失字段,可能让整个请求解析静默失败为默认值。
std::to_stringnlohmann/json#include
#include
#include
using json = nlohmann::json;
std::vector v = {1, 2, 3};
json j = v; // 自动转为 [1,2,3]
std::string s = j.dump(); // → "[1,2,3]"
nlohmann::jsonstd::vectorstd::mapstd::unordered_mapstd::vector> dump(2)dump()no matching function for call to 'to_json'
#include
struct Person {
std::string name;
int age;
};
// 必须在 Person 所在命名空间(或全局)中定义
void to_json(json& j, const Person& p) {
j = json{{"name", p.name}, {"age", p.age}};
}
void from_json(const json& j, Person& p) {
j.at("name").get_to(p.name);
j.at("age").get_to(p.age);
}
j.at("key")j["key"]std::vectorPersonstd::mapstd::unordered_mapstd::mapstd::vector> std::unordered_mapstd::stringstd::stringintstd::vectorjson j = my_vec;json::array()
json j = json::array();
j.reserve(my_vec.size()); // 预分配内存
for (const auto& x : my_vec) {
j.emplace_back(x); // 移动而非拷贝
}
reserve()to_jsonj.is_array()j.is_object()from_jsonat()[]