在现代软件开发中,JSON 已成为最通用的数据交换格式之一。Python、JavaScript 等语言对 JSON 的支持几乎是“内建级别”的——你可以像操作字典/对象一样自然地读写 JSON。而在 C++ 世界里,过去处理 JSON 的体验往往偏繁琐:模板库难用、语法冗长、集成麻烦。
JSON for Modern C++(即 nlohmann/json)的出现彻底改变了这一局面。它凭借现代 C++ 特性,让 JSON 在 C++ 中成为“一等公民”,提供接近动态语言的开发体验。目前,它是 C++ 社区最受欢迎、使用最广泛的 JSON 库之一(GitHub 46k+ star)。
通过运算符重载和模板推导,你可以像访问 std::map 和 std::vector 一样操作 JSON:
json j;j["name"] = "张三";j["age"] = 18;j["skills"] = {"C++", "Python"};
整个库仅由一个 json.hpp 头文件构成,无需编译、无需链接额外库。下载后直接 #include 即可使用,集成成本几乎为零。
除了基本读写外,还提供:
JSON Pointer / JSON Patch:按路径访问与差异化补丁
JSON Merge Patch:简洁的合并修改语法
二进制格式:BSON、CBOR、MessagePack 等,适合网络传输与存储优化
通过为自定义类型特化 to_json / from_json,即可自动完成序列化与反序列化:
struct Person { std::string name; int age; };voidto_json(json& j, const Person& p){j = json{{"name", p.name}, {"age", p.age}};}voidfrom_json(const json& j, Person& p){j.at("name").get_to(p.name);j.at("age").get_to(p.age);}
Person p{"Alice", 30};json j = p; // 序列化Person p2 = j.get<Person>(); // 反序列化
直接下载:将 json.hpp 放入项目目录,然后:
#include"json.hpp"using json = nlohmann::json;
包管理器:vcpkg、Conan、apt(Ubuntu)均可安装。
CMake:可使用 find_package(nlohmann_json REQUIRED)。
#include<iostream>#include<iomanip>#include"json.hpp"using json = nlohmann::json;intmain(){// 1. 使用初始化列表创建复杂 JSONjson data = {{"name", "Alice"},{"age", 30},{"is_student", false},{"grades", {88, 92, 76}},{"address", {{"city", "Beijing"}, {"country", "China"}}},{"languages", {"C++", "Python"}}};// 2. 动态修改/添加data["is_student"] = true;data["skills"] = {"JSON", "C++"};data["grades"].push_back(95);// 3. 漂亮打印std::cout << std::setw(4) << data << std::endl;// 4. 从字符串解析std::string json_str = R"({"name": "Bob", "age": 25})";json parsed = json::parse(json_str);std::cout << "Parsed name: " << parsed["name"] << std::endl;return 0;}
{"address": {"city": "Beijing","country": "China"},"age": 30,"grades": [88, 92, 76, 95],"is_student": true,"languages": ["C++", "Python"],"name": "Alice","skills": ["JSON", "C++"]}
#include<fstream>#include"json.hpp"intmain(){// 读取 JSON 文件std::ifstream fin("data.json");json j;fin >> j; // 自动解析// 修改j["new_key"] = "new_value";// 写入文件(带缩进)std::ofstream fout("data_modified.json");fout << std::setw(4) << j;return 0;}
nlohmann/json 的优势在于 开发效率,并非极致性能。下表(基于常见 Benchmark 趋势)可帮助你在项目中选择合适的库:
| nlohmann/json | ||||
| RapidJSON | ||||
| simdjson |
注:实际数据受测试环境、数据集大小影响,表中数值仅作趋势参考。
如果你的项目仍希望在该库基础上提升效率,可以尝试以下手段:
预分配数组内存对于大型数组,使用 reserve() 避免多次重分配:
json::array_t arr;arr.reserve(10000);j["big_data"] = std::move(arr);
2, 利用移动语义使用 std::move 转移 JSON 所有权,减少拷贝。
3.安全访问:at() 代替 operator[]在反序列化自定义类型时,at() 会在键不存在时抛出异常,避免未定义行为。
4. 嵌入式场景裁剪通过宏配置禁用异常、缩减代码体积(例如 #define JSON_NOEXCEPTION)。
选择 nlohmann/json 的场景:
目标是 快速开发、易于维护
处理配置、REST API 交互、中等规模数据交换
希望代码像 Python 一样优雅,降低团队学习成本
考虑其他高性能库(simdjson / RapidJSON)的场景:
每秒需解析几百 MB 甚至 GB 级 JSON(如高频交易、实时日志处理)
内存或 CPU 资源极度受限的嵌入式环境
总体而言,nlohmann/json 为 C++ 世界带来了动态语言般的愉悦体验。它可能不是最快的,但它一定是最“贴心”的。正如其名 —— 让 C++ 开发者也能享受现代 JSON 处理的乐趣。
如果你还没尝试过,不妨从下一个项目开始引入 nlohmann/json,相信你会爱上它。
*本文基于 nlohmann/json v3.11+ 编写。