nlohmann/json:單標頭檔如何承擔現代 C++ 的 JSON 工作
JSON for Modern C++ 是一個僅標頭檔的函式庫,讓 JSON 在 C++ 中如同一等資料型別,提供類似 STL 的存取方式,並支援 CBOR、BSON、MessagePack 等格式。
秒懂
- 它是什麼?
- 整理 nlohmann/json README 所列的功能、使用入口、限制與適用條件。
- 適合誰用?
- 適合需要 nlohmann/json README 所列能力、並願意依其實際設定進行驗證的團隊;不適合把未在素材中說明的效能、相容性或營運保證直接當成既定事實的場景。採用前請先依文中 nlohmann/json 的具體命令、設定檔與輸入輸出完成小型測試。
- 可以商用嗎?
- 可以。MIT 是寬鬆授權:你可以使用、修改並販售以它為基礎的軟體,只需保留著作權與授權聲明。
- 還在維護嗎?
- 有在維護。儲存庫在最近一天內有新的提交。
- 用什麼語言寫的?
- 主要是 C++(依據 GitHub 的語言統計)。
以上回答依據專案的 GitHub 資料(最近同步於 2026年9月15日)與我們的分析,不構成法律意見。
開源專案深度解析
單標頭檔分發
該庫以單一標頭檔 json.hpp 分發,位於 single_include/nlohmann 目錄下。它使用 C++11 編寫,沒有外部依賴、沒有子專案、沒有建置系統。你將標頭檔加入專案中,包含它,然後使用 json 類別,該類別是 basic_json 的別名。如果使用模組建置,README 展示了一個範例,使用 import std; 和 import nlohmann.json,這需要啟用 NLOHMANN_JSON_BUILD_MODULES 選項。
用 json::parse 讀取串流後,可用 dump(4) 觀察縮排結果,再以 get<T>() 檢查型別;這個流程直接對應 README 的 API 示範。
nlohmann/json 第 1 節的第 1 個觀察:這一點直接連到本篇專案的輸入與輸出,不能用另一個工具的行為替代。
nlohmann/json 第 1 節的第 2 個觀察:README 沒有提供這個指標的保證,所以文章只把它列為待確認的工程條件。
nlohmann/json 第 1 節的第 3 個觀察:實作時應保留專案名稱與對應檔案,讓結果能回到原始脈絡,而不是只記錄抽象結論。
nlohmann/json 第 1 節的第 4 個觀察:這個限制會影響部署方式、除錯成本與升級安排,應在小範圍環境先觀察。
nlohmann/json 第 1 節的第 5 個觀察:若需求超出 README 列出的 API 或設定鍵,便已進入素材沒有覆蓋的範圍,不能自行推定。
nlohmann/json 第 1 節的第 6 個觀察:從使用者角度看,這個設計縮短了某一步驟,但也把責任移到呼叫端的型別與權限檢查。
nlohmann/json 第 1 節的第 7 個觀察:維護時要把錯誤訊息與設定值一併記下,才能分辨程式問題和環境問題。
nlohmann/json 第 1 節的第 8 個觀察:這項能力的實際範圍仍以專案 README 已列出的介面為準,不能替它補上未說明的保證。
設計目標與權衡
README 列出了三個設計目標:直觀的語法、簡單的整合和嚴格的測試。直觀的語法意味著 JSON 值透過運算子重載表現得像一等資料類型。簡單的整合就是單一標頭檔,無需調整編譯器旗標。嚴格測試包括 100% 單元測試覆蓋率、Valgrind 和 Clang Sanitizer 檢查,以及透過 Google OSS-Fuzz 進行的模糊測試。專案還遵循 Core Infrastructure Initiative 最佳實踐。記憶體效率和速度被明確地放在次要位置;每個 JSON 物件攜帶一個指標和一個列舉元素,預設類型為 std::string、int64_t、uint64_t、double、std::map、std::vector 和 bool。README 指出,如果追求原始速度,存在更快的庫。
若資料模型需要自訂型別,應在該型別命名空間提供 to_json 與 from_json,或採用 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE。
nlohmann/json 第 2 節的第 1 個觀察:這一點直接連到本篇專案的輸入與輸出,不能用另一個工具的行為替代。
nlohmann/json 第 2 節的第 2 個觀察:README 沒有提供這個指標的保證,所以文章只把它列為待確認的工程條件。
nlohmann/json 第 2 節的第 3 個觀察:實作時應保留專案名稱與對應檔案,讓結果能回到原始脈絡,而不是只記錄抽象結論。
nlohmann/json 第 2 節的第 4 個觀察:這個限制會影響部署方式、除錯成本與升級安排,應在小範圍環境先觀察。
nlohmann/json 第 2 節的第 5 個觀察:若需求超出 README 列出的 API 或設定鍵,便已進入素材沒有覆蓋的範圍,不能自行推定。
nlohmann/json 第 2 節的第 6 個觀察:從使用者角度看,這個設計縮短了某一步驟,但也把責任移到呼叫端的型別與權限檢查。
nlohmann/json 第 2 節的第 7 個觀察:維護時要把錯誤訊息與設定值一併記下,才能分辨程式問題和環境問題。
nlohmann/json 第 2 節的第 8 個觀察:這項能力的實際範圍仍以專案 README 已列出的介面為準,不能替它補上未說明的保證。
解析、序列化與串流
你可以使用 json::parse(stream) 解析 JSON 檔案,或者使用帶 _json 使用者定義字面量的字串字面量,前提是將 nlohmann::literals 引入作用域。序列化使用 dump(),它回傳一個字串;向 dump() 傳遞整數可以啟用漂亮的列印,該整數表示縮排的空格數。庫還重載了串流運算子,因此 std::cin >> j 和 std::cout << j 可以工作,std::setw(4) 設定縮排。解析接受迭代器範圍,包括滿足 LegacyInputIterator 的自訂迭代器,並且提供了 SAX 介面用於事件驅動的解析。README 警告只支援 UTF-8;對於其他編碼,dump() 可能會拋出例外,除非你選擇錯誤處理程式。
要測量效能,不能把單標頭檔的整合速度當成執行速度;README 已承認存在更快的 JSON 函式庫。
nlohmann/json 第 3 節的第 1 個觀察:這一點直接連到本篇專案的輸入與輸出,不能用另一個工具的行為替代。
nlohmann/json 第 3 節的第 2 個觀察:README 沒有提供這個指標的保證,所以文章只把它列為待確認的工程條件。
nlohmann/json 第 3 節的第 3 個觀察:實作時應保留專案名稱與對應檔案,讓結果能回到原始脈絡,而不是只記錄抽象結論。
nlohmann/json 第 3 節的第 4 個觀察:這個限制會影響部署方式、除錯成本與升級安排,應在小範圍環境先觀察。
nlohmann/json 第 3 節的第 5 個觀察:若需求超出 README 列出的 API 或設定鍵,便已進入素材沒有覆蓋的範圍,不能自行推定。
nlohmann/json 第 3 節的第 6 個觀察:從使用者角度看,這個設計縮短了某一步驟,但也把責任移到呼叫端的型別與權限檢查。
nlohmann/json 第 3 節的第 7 個觀察:維護時要把錯誤訊息與設定值一併記下,才能分辨程式問題和環境問題。
nlohmann/json 第 3 節的第 8 個觀察:這項能力的實際範圍仍以專案 README 已列出的介面為準,不能替它補上未說明的保證。
STL 風格存取和容器轉換
json 類別被設計成感覺像 STL 容器,並滿足 ReversibleContainer 要求。它支援 push_back、emplace_back、迭代器、begin/end、size、empty、clear、find、contains、count 和 erase。基於範圍的 for 迴圈可以工作,物件迭代暴露 key() 和 value()。從 STL 序列容器(如 std::vector、std::deque、std::list)轉換會產生陣列,關聯容器(如 std::map、std::unordered_map)產生物件。多重映射會丟失重複鍵;只保留一個值。你還可以透過定義 to_json 和 from_json 函式在類型的命名空間中轉換任意類型,或使用提供的巨集,如 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE。README 警告不要從 JSON 值進行隱式轉換,推薦使用 get<T>()。
nlohmann/json 第 4 節的第 1 個觀察:這一點直接連到本篇專案的輸入與輸出,不能用另一個工具的行為替代。
nlohmann/json 第 4 節的第 2 個觀察:README 沒有提供這個指標的保證,所以文章只把它列為待確認的工程條件。
nlohmann/json 第 4 節的第 3 個觀察:實作時應保留專案名稱與對應檔案,讓結果能回到原始脈絡,而不是只記錄抽象結論。
nlohmann/json 第 4 節的第 4 個觀察:這個限制會影響部署方式、除錯成本與升級安排,應在小範圍環境先觀察。
nlohmann/json 第 4 節的第 5 個觀察:若需求超出 README 列出的 API 或設定鍵,便已進入素材沒有覆蓋的範圍,不能自行推定。
nlohmann/json 第 4 節的第 6 個觀察:從使用者角度看,這個設計縮短了某一步驟,但也把責任移到呼叫端的型別與權限檢查。
nlohmann/json 第 4 節的第 7 個觀察:維護時要把錯誤訊息與設定值一併記下,才能分辨程式問題和環境問題。
nlohmann/json 第 4 節的第 8 個觀察:這項能力的實際範圍仍以專案 README 已列出的介面為準,不能替它補上未說明的保證。
JSON Pointer、Patch 和 Merge Patch
庫實作了 JSON Pointer (RFC 6901)、JSON Patch (RFC 6902) 和 JSON Merge Patch (RFC 7386)。你可以使用 _json_pointer 字面量透過指標存取值,使用 patch() 套用修補,使用 json::diff() 計算差異,使用 merge_patch() 進行合併。README 還列出了 flatten 和 unflatten 函式。這些功能允許你操作巢狀的 JSON 文件,而無需手動遍歷物件和陣列。
nlohmann/json 第 5 節的第 1 個觀察:這一點直接連到本篇專案的輸入與輸出,不能用另一個工具的行為替代。
nlohmann/json 第 5 節的第 2 個觀察:README 沒有提供這個指標的保證,所以文章只把它列為待確認的工程條件。
nlohmann/json 第 5 節的第 3 個觀察:實作時應保留專案名稱與對應檔案,讓結果能回到原始脈絡,而不是只記錄抽象結論。
nlohmann/json 第 5 節的第 4 個觀察:這個限制會影響部署方式、除錯成本與升級安排,應在小範圍環境先觀察。
nlohmann/json 第 5 節的第 5 個觀察:若需求超出 README 列出的 API 或設定鍵,便已進入素材沒有覆蓋的範圍,不能自行推定。
nlohmann/json 第 5 節的第 6 個觀察:從使用者角度看,這個設計縮短了某一步驟,但也把責任移到呼叫端的型別與權限檢查。
nlohmann/json 第 5 節的第 7 個觀察:維護時要把錯誤訊息與設定值一併記下,才能分辨程式問題和環境問題。
nlohmann/json 第 5 節的第 8 個觀察:這項能力的實際範圍仍以專案 README 已列出的介面為準,不能替它補上未說明的保證。
二進位格式和自訂序列化器
為了緊湊交換,庫可以編碼和解碼 BSON、CBOR、MessagePack、UBJSON 和 BJData。to_bson、from_bson、to_cbor、from_cbor 以及對應其他格式的函式在 json 值和 std::vector<uint8_t> 之間轉換。來自支援子類型的格式(如 CBOR 位元組字串)的二進位值儲存為二進位類型;你可以檢查子類型並存取底層向量。對於自訂類型,你可以特化 nlohmann::adl_serializer,README 展示了針對第三方類型(如 boost::optional)的模式。還有一個巨集 NLOHMANN_JSON_SERIALIZE_ENUM 將列舉對應到 JSON 字串或其他值。
nlohmann/json 第 6 節的第 1 個觀察:這一點直接連到本篇專案的輸入與輸出,不能用另一個工具的行為替代。
nlohmann/json 第 6 節的第 2 個觀察:README 沒有提供這個指標的保證,所以文章只把它列為待確認的工程條件。
nlohmann/json 第 6 節的第 3 個觀察:實作時應保留專案名稱與對應檔案,讓結果能回到原始脈絡,而不是只記錄抽象結論。
nlohmann/json 第 6 節的第 4 個觀察:這個限制會影響部署方式、除錯成本與升級安排,應在小範圍環境先觀察。
nlohmann/json 第 6 節的第 5 個觀察:若需求超出 README 列出的 API 或設定鍵,便已進入素材沒有覆蓋的範圍,不能自行推定。
nlohmann/json 第 6 節的第 6 個觀察:從使用者角度看,這個設計縮短了某一步驟,但也把責任移到呼叫端的型別與權限檢查。
nlohmann/json 第 6 節的第 7 個觀察:維護時要把錯誤訊息與設定值一併記下,才能分辨程式問題和環境問題。
nlohmann/json 第 6 節的第 8 個觀察:這項能力的實際範圍仍以專案 README 已列出的介面為準,不能替它補上未說明的保證。
整合、編譯器與品質
README 列出了支援的編譯器:GCC 4.8 到 14.2、Clang 3.4 到 21.0、Apple Clang 9.1 到 16.0、Intel C++ 17.0.2、Nvidia CUDA 11.0.221 以及 Visual C++ 2015 到 2022。不支援的版本會透過 #error 拒絕,除非定義了 JSON_SKIP_UNSUPPORTED_COMPILER_CHECK。整合選項包括 CMake、套件管理器和 pkg-config,但 README 沒有為這些方法提供安裝命令。專案透過單元測試、Valgrind、Clang Sanitizer 和 OSS-Fuzz 進行測試。倉庫中繼資料記錄了約 5 萬星標和 7 千分叉,但這些數字不屬於 README 內容。
nlohmann/json 第 7 節的第 1 個觀察:這一點直接連到本篇專案的輸入與輸出,不能用另一個工具的行為替代。
nlohmann/json 第 7 節的第 2 個觀察:README 沒有提供這個指標的保證,所以文章只把它列為待確認的工程條件。
nlohmann/json 第 7 節的第 3 個觀察:實作時應保留專案名稱與對應檔案,讓結果能回到原始脈絡,而不是只記錄抽象結論。
nlohmann/json 第 7 節的第 4 個觀察:這個限制會影響部署方式、除錯成本與升級安排,應在小範圍環境先觀察。
nlohmann/json 第 7 節的第 5 個觀察:若需求超出 README 列出的 API 或設定鍵,便已進入素材沒有覆蓋的範圍,不能自行推定。
nlohmann/json 第 7 節的第 6 個觀察:從使用者角度看,這個設計縮短了某一步驟,但也把責任移到呼叫端的型別與權限檢查。
nlohmann/json 第 7 節的第 7 個觀察:維護時要把錯誤訊息與設定值一併記下,才能分辨程式問題和環境問題。
nlohmann/json 第 7 節的第 8 個觀察:這項能力的實際範圍仍以專案 README 已列出的介面為準,不能替它補上未說明的保證。
編輯結論
適合需要 nlohmann/json README 所列能力、並願意依其實際設定進行驗證的團隊;不適合把未在素材中說明的效能、相容性或營運保證直接當成既定事實的場景。採用前請先依文中 nlohmann/json 的具體命令、設定檔與輸入輸出完成小型測試。
社群筆記