news 2026/9/8 12:29:11

nlohmann json C++ 库实战:一个头文件到底够不够用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
nlohmann json C++ 库实战:一个头文件到底够不够用

nlohmann json C++ 库实战:一个头文件到底够不够用

【免费下载链接】jsonJSON for Modern C++项目地址: https://gitcode.com/GitHub_Trending/js/json

nlohmann json C++ 库(nlohmann/json)是一个单头文件的 C++ JSON 库,include 一个文件就能完成解析、修改、序列化,面向不想引入构建依赖的开发者,适合中小型项目和工具类代码。

🚀 nlohmann json 单头文件三步编译运行

从拿到代码到打印第一个结果,最短路径是四步:

  1. 克隆仓库:git clone https://gitcode.com/GitHub_Trending/js/json
  2. 写一个样例文件,includesingle_include/下的头文件
  3. 编译:g++ -std=c++11 -I json/single_include main.cpp -o demo
  4. 运行./demo
#include <nlohmann/json.hpp> #include <iostream> using json = nlohmann::json; int main() { json j = {{"name", "json"}, {"version", "3.12.0"}}; std::cout << j.dump(2) << std::endl; }

这段代码构造了一个两字段对象,并用两格缩进打印出来,输出的就是熟悉的 JSON 结构。

为什么是单文件、零依赖

这个设计是拿编译时间换集成成本。单文件意味着放进任何工程都不用改构建系统,零依赖意味着不用追第三方包的版本。

这个单文件并不是手写的。源码实际放在include/nlohmann/目录,按输入、输出、迭代器等模块拆分,再由tools/amalgamate/里的脚本自动合并生成single_include/nlohmann/json.hpp。两条使用路径始终同步,你不需要关心哪份是"正本"。

代价是编译耗时:头文件约两万多行,包含它的每个编译单元都比普通库慢一些。多数项目可以接受;如果编译时间确实是瓶颈,C++20 用户可以用仓库自带的模块版本src/modules/json.cppm

📁 nlohmann json 读写配置文件

先看最常见的场景:从文件读配置,缺省值兜底。

json config; std::ifstream f("config.json"); f >> config; std::string host = config.value("host", "localhost"); int port = config.value("port", 8080); for (auto& [key, value] : config.items()) { std::cout << key << " = " << value << "\n"; }

这段代码把文件整体读成 json 对象,用value()安全取两个字段(键不存在时返回默认值),再遍历打印全部键值对。

对象内部的嵌套结构同样直接。j["a"]["b"]一路写下去就能构造深层嵌套,和写 JavaScript 对象几乎一样,不需要先声明类型再逐层填充。

🧩 nlohmann json 自定义类型序列化 to_json from_json

结构体和 JSON 的互转,靠两个自由函数完成:

struct Person { std::string name; int age; }; 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); } Person p{"Ada", 36}; json j = p; // 自动序列化 Person q = j.get<Person>(); // 自动反序列化

库通过 ADL 机制在赋值和get<T>()时找到你定义的to_json/from_json,业务代码里就只剩两次转换。

📍 用 JSON Pointer 和 JSON Patch 做增量修改

定位深层字段不必层层取值,RFC 6901 风格的指针可以直接寻址;修改整棵树的增量操作则交给 JSON Patch:

json j = R"({"server": {"port": 8080, "hosts": ["a", "b"]}})"_json; std::cout << j["/server/hosts/1"_json_pointer] << std::endl; // b json source = {{"baz", "qux"}, {"foo", "bar"}}; json patch = R"([{"op": "replace", "path": "/baz", "value": "boo"}, {"op": "remove", "path": "/foo"}])"_json; std::cout << source.patch(patch) << std::endl;

前四行用指针/server/hosts/1取出数组第二个元素;后四行把一段 patch 描述应用到 source 上,得到{"baz":"boo"}。远程配置下发、协作编辑这类"传操作不传全量"的场景可以直接套用。

⚖️ 能力边界:哪些场景该换库

它擅长的是一般业务场景:配置读取、接口数据交换,以及 CBOR、MessagePack、BSON 等二进制格式之间的互转,Pointer 和 Patch 也内置。

不适合的是追求极限解析速度的热路径,以及内存受限环境。从仓库自带的官方 benchmark 看,它的解析耗时在一二十个库里处于中游:

nlohmann json C++ 库解析耗时 benchmark 对比图.png>)

日常够用,但不是最快。性能敏感时可以考虑替代方案:

关注点nlohmann/jsonRapidJSONsimdjson
集成成本拷贝一个头文件需构建需构建
API 风格运算符重载,写法像 PythonDOM/SAX 双模式,偏底层解析器优先,单线程最快
适合场景通用业务,中小 JSON性能与内存敏感大批量数据解析

🔌 工程集成:CMake 拉取与包管理器

CMake 工程推荐用 FetchContent 把仓库拉成依赖:

include(FetchContent) FetchContent_Declare(nlohmann_json GIT_REPOSITORY https://gitcode.com/GitHub_Trending/js/json GIT_TAG master) FetchContent_MakeAvailable(nlohmann_json) target_link_libraries(app PRIVATE nlohmann_json::nlohmann_json)

这段配置把库变成一个普通的 CMake 目标,后续升级只改GIT_TAG

没有构建系统的工程,直接把single_include/nlohmann/json.hpp拷进自己的 include 目录即可。包管理器渠道也齐全:vcpkg 执行vcpkg install nlohmann-json,Homebrew 执行brew install nlohmann-json,Ubuntu 执行apt install nlohmann-json3-dev,Conan 可搜到nlohmann_json配方。版本变化记录在 ChangeLog.md,API 细节查 官方文档。

⚠️ 常见坑与实用技巧

const json 上 operator[] 会抛异常。只读场景不能用j["key"],它试图构造键。改用j.value("key", 默认值)j.at("key"),前者缺键时安静返回默认值,后者抛out_of_range便于定位问题。

dump 默认转义中文。非 ASCII 字符会变成\uXXXX序列。要让中文原样输出,用j.dump(2, false),第二个参数就是ensure_ascii

对象同键赋值会覆盖。对同一键二次赋值,旧值直接丢失。如果语义是"不存在才插入",用j.emplace("key", value)

可以先拿单头文件跑起来验证配置处理需求;如果业务涉及高频解析大数据,建议先做一轮基准测试再定。对大多数 C++ 项目来说,它是那个不用想太多就能上手的 JSON 库。

【免费下载链接】jsonJSON for Modern C++项目地址: https://gitcode.com/GitHub_Trending/js/json

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 13:02:11

项目文档:基于Python与OpenCV的四步相移相位解调系统设计与实现

摘要&#xff1a;随着计算机视觉、模式识别和图形化交互技术的发展&#xff0c;手写数字识别在邮政编码识别、票据处理、表单录入、教育实验和智能人机交互等场景中具有较高的应用价值。 内容简介 四步相移相位解调技术是结构光三维测量、精密检测和机器视觉领域中的核心方法之…

作者头像 李华
网站建设 2026/9/5 13:11:29

软件工程复杂性管理:从软件危机到订单状态机重构

软件工程导论类课程通常把“软件危机”放在第一章&#xff0c;原因是软件行业最原始的驱动力并不是更快的技术&#xff0c;而是对复杂度的控制。一个几百行的脚本可以靠人脑装下&#xff0c;一个几十万行的业务系统如果没有任何结构&#xff0c;负责维护的人会很快失去掌控。“…

作者头像 李华
网站建设 2026/9/5 20:22:29

Getting Real:少即是多的软件交付方法论与工程实践

这次我们不聊一个下载下来就能跑的模型&#xff0c;而是一个经常被误读的软件方法论&#xff1a;“Getting Real”。它出自 37signals&#xff08;现 Basecamp 团队&#xff09;的同名作品&#xff0c;核心思想不是“做更多功能”&#xff0c;而是“用最小的团队、最短的时间&a…

作者头像 李华