nlohmann/json需手动映射c++对象到json,通过同命名空间的to_json函数实现adl查找;基础类型直构,自定义类须显式定义to_json;dump()默认紧凑格式,可选缩进或禁转义unicode。

怎么用 nlohmann/json 把 C++ 对象转成 JSON 字符串
直接调用 nlohmann::json 的构造函数或赋值操作,把对象字段一个个塞进去,再用 .dump() 输出字符串。它不支持自动反射,必须手动映射——这不是缺陷,是设计选择:避免运行时开销和 ABI 依赖。
常见错误是试图传入裸指针或未定义 to_json 的自定义类型,结果编译失败,报错像 no matching function for call to ‘to_json’ 或 invalid operands to binary expression。
- 基础类型(
int、std::string、std::vector)可直接构造:nlohmann::json j = std::vector{1, 2, 3}; - 自定义类必须显式定义
to_json函数,且必须在类定义所在命名空间内(不能在全局或std里) - 如果对象含
const成员或私有字段,to_json里得用友元或 public getter 访问
to_json 函数写在哪?为什么放错位置就编译不过
to_json 必须和目标类在同一个命名空间里,nlohmann 通过 ADL(Argument-Dependent Lookup)查找它。放在全局命名空间或匿名命名空间里,编译器根本找不到。
比如类 Person 在 ns 命名空间中,to_json 就得写在 ns 里,不能写在 :: 下或 nlohmann 内部。
本文档主要讲述的是JSON.NET 简单的使用;JSON.NET使用来将.NET中的对象转换为JSON字符串(序列化),或者将JSON字符串转换为.NET中已有类型的对象(反序列化?)。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
立即学习“C++免费学习笔记(深入)”;
- 正确写法:
namespace ns { struct Person { std::string name; int age; }; void to_json(nlohmann::json& j, const Person& p) { j["name"] = p.name; j["age"] = p.age; } } - 错误写法:
void to_json(...)写在main()外但没包在ns里,或加了static - 如果类模板化,
to_json也得是模板,并显式特化或泛化匹配
dump() 有哪些常用参数?什么时候该用 indent
.dump() 默认输出紧凑格式(无空格无换行),适合网络传输;加参数能控制可读性,但会明显增大字符串长度,别在日志或序列化密集场景滥用。
-
j.dump()→{"name":"Alice","age":30} -
j.dump(2)→ 每级缩进 2 空格,换行,适合调试或配置文件输出 -
j.dump(-1)→ 不转义 Unicode(如保留中文原字符),默认是转成\uXXXX形式 - 注意:带缩进的字符串不能直接用于 HTTP body 的
application/json,虽合法但浪费带宽;生产环境建议用紧凑格式
遇到中文乱码或特殊字符被转义怎么办
nlohmann 默认把非 ASCII 字符转成 \uXXXX,看着像乱码其实是标准行为。想显示原文,得用 dump(-1);但更要紧的是确认源字符串编码是 UTF-8——它只认 UTF-8,输入 GBK 或 UTF-16 会导致输出异常甚至崩溃。
- Windows 上用
std::filesystem::path或std::string读文件时,确保以 UTF-8 打开(例如用std::ifstream配合std::codecvt_utf8或 C++20 的std::from_chars转换) - Qt 用户注意:
QString::toUtf8().toStdString()是安全的;直接用QString::toStdString()可能返回本地编码 - JSON 标准只要求 UTF-8,所以服务端接收时也应按 UTF-8 解析,别在中间层做额外 decode
最常被忽略的一点:to_json 函数里对 std::string 成员不做任何编码转换——它假设你给的就是合法 UTF-8。传进去的是乱码,输出就是乱码,库不会帮你救。









