json - 最新の C++ のための JSON

(JSON for Modern C++)

Created at: 2013-07-04 16:47:49
Language: C++
License: MIT

最新の C++ のための JSON

ビルドステータス ウブンツ マック ウィンドウズ カバレッジステータス カバー性スキャンのビルドステータス コーダシーバッジ 言語グレード:C / C ++ ファジングステータス オンラインで試す ドキュメンテーション GitHub ライセンス GitHub リリース 梱包状況 GitHub ダウンロード GitHub の問題 問題解決にかかる平均時間 CIIのベストプラクティス GitHub スポンサー 再利用ステータス 不和

設計目標

そこには無数のJSONライブラリがあり、それぞれが存在する理由さえあるかもしれません。私たちのクラスには、次の設計目標がありました。

  • 直感的な構文。Python などの言語では、JSON はファーストクラスのデータ型のように感じられます。最新のC ++のすべての演算子の魔法を使用して、コードで同じ感覚を実現しました。以下の例をチェックすると、私が何を意味するのかがわかります。

  • 些細な統合。コード全体は、単一のヘッダーファイル json.hpp で構成されています。それです。ライブラリ、サブプロジェクト、依存関係、複雑なビルドシステムはありません。クラスはバニラC ++ 11で書かれています。全体として、コンパイラフラグやプロジェクト設定を調整する必要はありません。

  • 真剣なテスト。私たちのコードは徹底的に単体テストされており、すべての例外的な動作を含め、コードの100%をカバーしています。さらに、ValgrindClangサニタイザーにメモリリークがないことを確認しました。Google OSS-Fuzzはさらに、すべてのパーサーに対してファジーテストを24時間年中無休で実行し、これまでに数十億のテストを効果的に実行します。高品質を維持するために、プロジェクトはコアインフラストラクチャイニシアチブ(CII)のベストプラクティスに従っています。

他の側面は私たちにとってそれほど重要ではありませんでした:

  • メモリ効率。各 JSON オブジェクトには、1 つのポインター (共用体の最大サイズ) と 1 つの列挙要素 (1 バイト) のオーバーヘッドがあります。既定の汎化では、文字列、、または数値、オブジェクト、配列、およびブール値の C++ データ型が使用されます。ただし、一般化されたクラスをニーズに合わせてテンプレート化できます。

    std::string
    int64_t
    uint64_t
    double
    std::map
    std::vector
    bool
    basic_json

  • スピード確かにそこにはより高速なJSONライブラリがあります。ただし、単一のヘッダーでJSONサポートを追加することで開発をスピードアップすることが目標である場合は、このライブラリが最適です。またはの使用方法がわかっている場合は、すでに設定されています。

    std::vector
    std::map

詳細については、投稿ガイドラインを参照してください。

スポンサー

このライブラリは GitHub スポンサーでスポンサーできます。

🏢企業スポンサー

🏷️指定スポンサー

みんなありがとう!

支える

質問がある場合は、FAQまたはQ&Aセクションですでに回答されているかどうかを確認してください。そうでない場合は、そこで新しい質問をしてください

📚ライブラリの使用方法について詳しく知りたい場合は、READMEの残りの部分を確認するか、コード例を確認するか、ヘルプページを参照してください。

🚧API をよりよく理解したい場合は、API リファレンスを参照してください。

🐛バグを見つけた場合は、FAQで既知の問題なのか、設計上の決定の結果なのかを確認してください。新しい課題を作成する前に、課題リストも併せてご確認ください。問題を理解して再現するために、できるだけ多くの情報を提供してください。

ドキュメントブラウザDashVelocityおよびZeal用のドキュメントセットもあり、オフラインリソースとして完全なドキュメントが含まれています。

クラスの使用方法を理解するための例をいくつか示します。

以下の例のほかに、次のことを実行できます。

ドキュメント
を確認する→ スタンドアロンのサンプルファイルを参照する

すべての API 関数 (API ドキュメントに記載) には、対応するスタンドアロンのサンプルファイルがあります。たとえば、emplace() 関数には、一致する emplace.cpp サンプルファイルがあります。

ファイルから JSON を読み取る

このクラスは、JSON 値を操作するための API を提供します。JSON ファイルを読み取ってオブジェクトを作成するには:

json
json

#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

// ...

std::ifstream f("example.json");
json data = json::parse(f);

JSON リテラルからのオブジェクトの作成
json

このリテラル JSON 値をオブジェクトとしてファイルにハードコーディングするとします。

json

{
  "pi": 3.141,
  "happy": true
}

さまざまなオプションがあります。

// Using (raw) string literals and json::parse
json ex1 = json::parse(R"(
  {
    "pi": 3.141,
    "happy": true
  }
)");

// Using user-defined (raw) string literals
using namespace nlohmann::literals;
json ex2 = R"(
  {
    "pi": 3.141,
    "happy": true
  }
)"_json;

// Using initializer lists
json ex3 = {
  {"happy", true},
  {"pi", 3.141},
};

ファーストクラスのデータ型としてのJSONは

クラスの使用方法を理解するための例をいくつか示します。

JSON オブジェクトを作成するとします。

{
  "pi": 3.141,
  "happy": true,
  "name": "Niels",
  "nothing": null,
  "answer": {
    "everything": 42
  },
  "list": [1, 0, 2],
  "object": {
    "currency": "USD",
    "value": 42.99
  }
}

このライブラリを使用すると、次のように記述できます。

// create an empty structure (null)
json j;

// add a number that is stored as double (note the implicit conversion of j to an object)
j["pi"] = 3.141;

// add a Boolean that is stored as bool
j["happy"] = true;

// add a string that is stored as std::string
j["name"] = "Niels";

// add another null object by passing nullptr
j["nothing"] = nullptr;

// add an object inside the object
j["answer"]["everything"] = 42;

// add an array that is stored as std::vector (using an initializer list)
j["list"] = { 1, 0, 2 };

// add another object (using an initializer list of pairs)
j["object"] = { {"currency", "USD"}, {"value", 42.99} };

// instead, you could also write (which looks very similar to the JSON above)
json j2 = {
  {"pi", 3.141},
  {"happy", true},
  {"name", "Niels"},
  {"nothing", nullptr},
  {"answer", {
    {"everything", 42}
  }},
  {"list", {1, 0, 2}},
  {"object", {
    {"currency", "USD"},
    {"value", 42.99}
  }}
};

これらすべての場合において、使用するJSON値型をコンパイラに「指示」する必要はありません。いくつかのエッジケースを明示したり表現したりしたい場合は、関数json::array()とjson::object()が役立ちます。

// a way to express the empty array []
json empty_array_explicit = json::array();

// ways to express the empty object {}
json empty_object_implicit = json({});
json empty_object_explicit = json::object();

// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });

シリアル化/逆シリアル化

文字列の宛先/終了

JSON 値 (逆シリアル化) を作成するには、文字列リテラルに追加します。

_json

// create object from string literal
json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;

// or even nicer with a raw string literal
auto j2 = R"(
  {
    "happy": true,
    "pi": 3.141
  }
)"_json;

サフィックスを追加しないと、渡された文字列リテラルは解析されず、JSON文字列として使用されるだけであることに注意してください 価値。つまり、実際のオブジェクトを解析するのではなく、文字列を格納するだけです。

_json
json j = "{ \"happy\": true, \"pi\": 3.141 }"
"{ "happy": true, "pi": 3.141 }"

文字列リテラルは (json::p arse() を参照) を使用してスコープに入れる必要があります。

using namespace nlohmann::literals;

上記の例は、json::p arse() を使用して明示的に表現することもできます。

// parse explicitly
auto j3 = json::parse(R"({"happy": true, "pi": 3.141})");

JSON 値の文字列表現を取得することもできます (シリアル化)。

// explicit conversion to string
std::string s = j.dump();    // {"happy":true,"pi":3.141}

// serialization with pretty printing
// pass in the amount of spaces to indent
std::cout << j.dump(4) << std::endl;
// {
//     "happy": true,
//     "pi": 3.141
// }

シリアル化と代入の違いに注意してください。

// store a string in a JSON value
json j_string = "this is a string";

// retrieve the string value
auto cpp_string = j_string.get<std::string>();
// retrieve the string value (alternative when a variable already exists)
std::string cpp_string2;
j_string.get_to(cpp_string2);

// retrieve the serialized value (explicit JSON serialization)
std::string serialized_string = j_string.dump();

// output of original string
std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::string>() << '\n';
// output of serialized value
std::cout << j_string << " == " << serialized_string << std::endl;

.dump() は、最初に格納された文字列値を返します。

ライブラリはUTF-8のみをサポートしていることに注意してください。異なるエンコーディングの文字列をライブラリに格納する場合、dump() を呼び出すと、エラーハンドラとして使用されない限り、例外がスローされる可能性があります。

json::error_handler_t::replace
json::error_handler_t::ignore

ストリームの宛先/ストリームからの変換(ファイル、文字列ストリームなど)

ストリームを使用して、シリアル化および逆シリアル化することもできます。

// deserialize from standard input
json j;
std::cin >> j;

// serialize to standard output
std::cout << j;

// the setw manipulator was overloaded to set the indentation for pretty printing
std::cout << std::setw(4) << j << std::endl;

これらの演算子は、または の任意のサブクラスに対して機能します。ファイルと同じ例を次に示します。

std::istream
std::ostream

// read a JSON file
std::ifstream i("file.json");
json j;
i >> j;

// write prettified JSON to another file
std::ofstream o("pretty.json");
o << std::setw(4) << j << std::endl;

の例外ビットの設定は、このユースケースには不適切であることに注意してください。使用中の指定子が原因でプログラムが終了します。

failbit
noexcept

反復子範囲からの読み取り

イテレータ範囲からJSONを解析することもできます。つまり、1、2、または4バイトの整数型であるイテレータによってアクセス可能なコンテナからであり、それぞれUTF-8、UTF-16、UTF-32として解釈されます。たとえば、 、または :

value_type
std::vector<std::uint8_t>
std::list<std::uint16_t>

std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
json j = json::parse(v.begin(), v.end());

範囲[開始、終了]のイテレータを残すことができます:

std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
json j = json::parse(v);

カスタムデータソース

parse 関数は任意の反復子範囲を受け入れるため、この概念を実装することで独自のデータ ソースを提供できます。

LegacyInputIterator

struct MyContainer {
  void advance();
  const char& get_current();
};

struct MyIterator {
    using difference_type = std::ptrdiff_t;
    using value_type = char;
    using pointer = const char*;
    using reference = const char&;
    using iterator_category = std::input_iterator_tag;

    MyIterator& operator++() {
        MyContainer.advance();
        return *this;
    }

    bool operator!=(const MyIterator& rhs) const {
        return rhs.target != target;
    }

    reference operator*() const {
        return target.get_current();
    }

    MyContainer* target = nullptr;
};

MyIterator begin(MyContainer& tgt) {
    return MyIterator{&tgt};
}

MyIterator end(const MyContainer&) {
    return {};
}

void foo() {
    MyContainer c;
    json j = json::parse(c);
}

SAX インターフェイス

ライブラリは、次の機能を備えたSAXライクなインターフェイスを使用します。

// called when null is parsed
bool null();

// called when a boolean is parsed; value is passed
bool boolean(bool val);

// called when a signed or unsigned integer number is parsed; value is passed
bool number_integer(number_integer_t val);
bool number_unsigned(number_unsigned_t val);

// called when a floating-point number is parsed; value and original string is passed
bool number_float(number_float_t val, const string_t& s);

// called when a string is parsed; value is passed and can be safely moved away
bool string(string_t& val);
// called when a binary value is parsed; value is passed and can be safely moved away
bool binary(binary_t& val);

// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known)
bool start_object(std::size_t elements);
bool end_object();
bool start_array(std::size_t elements);
bool end_array();
// called when an object key is parsed; value is passed and can be safely moved away
bool key(string_t& val);

// called when a parse error occurs; byte position, the last token, and an exception is passed
bool parse_error(std::size_t position, const std::string& last_token, const detail::exception& ex);

各関数の戻り値によって、解析を続行するかどうかが決まります。

独自の SAX ハンドラーを実装するには、次の手順に従います。

  1. クラスに SAX インターフェイスを実装します。クラスを基本クラスとして使用できますが、上記の関数が実装され公開されている任意のクラスを使用することもできます。
    nlohmann::json_sax<json>
  2. SAX インターフェイス クラスのオブジェクトを作成します。
    my_sax
  3. 呼び出し;ここで、最初のパラメーターは文字列や入力ストリームなどの任意の入力で、2 番目のパラメーターは SAX インターフェイスへのポインターです。
    bool json::sax_parse(input, &my_sax)

この関数は、最後に実行されたSAXイベントの結果を示すaのみを返すことに注意してください。値は返されません - SAXイベントをどうするかを決めるのはあなた次第です。さらに、解析エラーの場合に例外はスローされません - 実装に渡された例外オブジェクトをどうするかはあなた次第です。内部的には、SAX インターフェイスは DOM パーサー (クラス) とアクセプタ () に使用されます (ファイル json_sax.hpp を参照)。

sax_parse
bool
json
parse_error
json_sax_dom_parser
json_sax_acceptor

STLのようなアクセス

JSON クラスは、STL コンテナーのように動作するように設計されています。実際、リバーシブルコンテナの要件を満たしています。

// create an array using push_back
json j;
j.push_back("foo");
j.push_back(1);
j.push_back(true);

// also use emplace_back
j.emplace_back(1.78);

// iterate the array
for (json::iterator it = j.begin(); it != j.end(); ++it) {
  std::cout << *it << '\n';
}

// range-based for
for (auto& element : j) {
  std::cout << element << '\n';
}

// getter/setter
const auto tmp = j[0].get<std::string>();
j[1] = 42;
bool foo = j.at(2);

// comparison
j == R"(["foo", 1, true, 1.78])"_json;  // true

// other stuff
j.size();     // 4 entries
j.empty();    // false
j.type();     // json::value_t::array
j.clear();    // the array is empty again

// convenience type checkers
j.is_null();
j.is_boolean();
j.is_number();
j.is_object();
j.is_array();
j.is_string();

// create an object
json o;
o["foo"] = 23;
o["bar"] = false;
o["baz"] = 3.141;

// also use emplace
o.emplace("weather", "sunny");

// special iterator member functions for objects
for (json::iterator it = o.begin(); it != o.end(); ++it) {
  std::cout << it.key() << " : " << it.value() << "\n";
}

// the same code as range for
for (auto& el : o.items()) {
  std::cout << el.key() << " : " << el.value() << "\n";
}

// even easier with structured bindings (C++17)
for (auto& [key, value] : o.items()) {
  std::cout << key << " : " << value << "\n";
}

// find an entry
if (o.contains("foo")) {
  // there is an entry with key "foo"
}

// or via find and an iterator
if (o.find("foo") != o.end()) {
  // there is an entry with key "foo"
}

// or simpler using count()
int foo_present = o.count("foo"); // 1
int fob_present = o.count("fob"); // 0

// delete an entry
o.erase("foo");

STL コンテナからの変換

JSON 値の構築に使用できるシーケンスコンテナ (, ) (整数、浮動小数点数、ブール値、文字列型、またはこのセクションで説明する STL コンテナなど) を使用して、JSON 配列を作成できます。同様の連想コンテナ(、)についても同じことが言えますが、これらの場合、配列の要素の順序は、それぞれのSTLコンテナでの要素の順序によって異なります。

std::array
std::vector
std::deque
std::forward_list
std::list
std::set
std::multiset
std::unordered_set
std::unordered_multiset

std::vector<int> c_vector {1, 2, 3, 4};
json j_vec(c_vector);
// [1, 2, 3, 4]

std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6};
json j_deque(c_deque);
// [1.2, 2.3, 3.4, 5.6]

std::list<bool> c_list {true, true, false, true};
json j_list(c_list);
// [true, true, false, true]

std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
json j_flist(c_flist);
// [12345678909876, 23456789098765, 34567890987654, 45678909876543]

std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};
json j_array(c_array);
// [1, 2, 3, 4]

std::set<std::string> c_set {"one", "two", "three", "four", "one"};
json j_set(c_set); // only one entry for "one" is used
// ["four", "one", "three", "two"]

std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};
json j_uset(c_uset); // only one entry for "one" is used
// maybe ["two", "three", "four", "one"]

std::multiset<std::string> c_mset {"one", "two", "one", "four"};
json j_mset(c_mset); // both entries for "one" are used
// maybe ["one", "two", "one", "four"]

std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};
json j_umset(c_umset); // both entries for "one" are used
// maybe ["one", "two", "one", "four"]

同様に、キーを構築でき、その値を使用して JSON 値を構築できる連想キー値コンテナー (、) (上記の例を参照) を使用して、JSON オブジェクトを作成できます。マルチマップの場合、JSONオブジェクトで使用されるキーは1つだけであり、値はSTLコンテナの内部順序に依存することに注意してください。

std::map
std::multimap
std::unordered_map
std::unordered_multimap
std::string

std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
json j_map(c_map);
// {"one": 1, "three": 3, "two": 2 }

std::unordered_map<const char*, double> c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} };
json j_umap(c_umap);
// {"one": 1.2, "two": 2.3, "three": 3.4}

std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
json j_mmap(c_mmap); // only one entry for key "three" is used
// maybe {"one": true, "two": true, "three": true}

std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
json j_ummap(c_ummap); // only one entry for key "three" is used
// maybe {"one": true, "two": true, "three": true}

JSON ポインターと JSON パッチ

ライブラリは、構造化値に対処するための代替手段として JSON ポインター (RFC 6901) をサポートしています。これに加えて、JSONパッチ(RFC 6902)は、2つのJSON値の違いを記述することを可能にし、Unixで知られているパッチと差分操作を効果的に許可します。

// a JSON value
json j_original = R"({
  "baz": ["one", "two", "three"],
  "foo": "bar"
})"_json;

// access members with a JSON pointer (RFC 6901)
j_original["/baz/1"_json_pointer];
// "two"

// a JSON patch (RFC 6902)
json j_patch = R"([
  { "op": "replace", "path": "/baz", "value": "boo" },
  { "op": "add", "path": "/hello", "value": ["world"] },
  { "op": "remove", "path": "/foo"}
])"_json;

// apply the patch
json j_result = j_original.patch(j_patch);
// {
//    "baz": "boo",
//    "hello": ["world"]
// }

// calculate a JSON patch from two JSON values
json::diff(j_result, j_original);
// [
//   { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] },
//   { "op": "remove","path": "/hello" },
//   { "op": "add", "path": "/foo", "value": "bar" }
// ]

JSON マージパッチ

ライブラリは、パッチ形式として JSON マージ パッチ (RFC 7386) をサポートしています。JSONポインター(上記を参照)を使用して操作する値を指定する代わりに、変更されるドキュメントを厳密に模倣した構文を使用して変更を記述します。

// a JSON value
json j_document = R"({
  "a": "b",
  "c": {
    "d": "e",
    "f": "g"
  }
})"_json;

// a patch
json j_patch = R"({
  "a":"z",
  "c": {
    "f": null
  }
})"_json;

// apply the patch
j_document.merge_patch(j_patch);
// {
//  "a": "z",
//  "c": {
//    "d": "e"
//  }
// }

暗黙的な変換

サポートされている型は、暗黙的に JSON 値に変換できます。

JSON 値からの暗黙的な変換は使用しないことをお勧めします。 この推奨事項の詳細については、こちらをご覧ください。 暗黙的な変換をオフにするには、ヘッダーを含める前に to を定義します。CMake を使用する場合は、オプションを に設定することでこれを実現することもできます。

JSON_USE_IMPLICIT_CONVERSIONS
0
json.hpp
JSON_ImplicitConversions
OFF

// strings
std::string s1 = "Hello, world!";
json js = s1;
auto s2 = js.get<std::string>();
// NOT RECOMMENDED
std::string s3 = js;
std::string s4;
s4 = js;

// Booleans
bool b1 = true;
json jb = b1;
auto b2 = jb.get<bool>();
// NOT RECOMMENDED
bool b3 = jb;
bool b4;
b4 = jb;

// numbers
int i = 42;
json jn = i;
auto f = jn.get<double>();
// NOT RECOMMENDED
double f2 = jb;
double f3;
f3 = jb;

// etc.

型は自動的に JSON 文字列に変換されず、整数に変換されることに注意してください。文字列への変換は明示的に指定する必要があります。

char

char ch = 'A';                       // ASCII value 65
json j_default = ch;                 // stores integer number 65
json j_string = std::string(1, ch);  // stores string "A"

任意の型変換

STL コンテナーやスカラー型だけでなく、すべての型を JSON でシリアル化できます。通常、あなたはそれらの行に沿って何かをするでしょう:

namespace ns {
    // a simple struct to model a person
    struct person {
        std::string name;
        std::string address;
        int age;
    };
}

ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};

// convert to JSON: copy each value into the JSON object
json j;
j["name"] = p.name;
j["address"] = p.address;
j["age"] = p.age;

// ...

// convert from JSON: copy each value from the JSON object
ns::person p {
    j["name"].get<std::string>(),
    j["address"].get<std::string>(),
    j["age"].get<int>()
};

それは機能しますが、それはかなり多くの定型文です...幸いなことに、もっと良い方法があります:

// create a person
ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60};

// conversion: person -> json
json j = p;

std::cout << j << std::endl;
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}

// conversion: json -> person
auto p2 = j.get<ns::person>();

// that's it
assert(p == p2);

基本的な使い方

これをいずれかの型で機能させるには、次の 2 つの関数を提供するだけで済みます。

using json = nlohmann::json;

namespace ns {
    void to_json(json& j, const person& p) {
        j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}};
    }

    void from_json(const json& j, person& p) {
        j.at("name").get_to(p.name);
        j.at("address").get_to(p.address);
        j.at("age").get_to(p.age);
    }
} // namespace ns

それだけです!型でコンストラクターを呼び出すと、カスタム メソッドが自動的に呼び出されます。 同様に、または を呼び出すと、メソッドが呼び出されます。

json
to_json
get<your_type>()
get_to(your_type&)
from_json

いくつかの重要なこと:

  • これらのメソッドは、型の名前空間(グローバル名前空間にすることができます)にある必要があり、そうしないとライブラリはそれらを見つけることができません(この例では、名前空間、 が定義されている場所)。
    ns
    person
  • これらのメソッドは、これらの変換を使用するすべての場所で利用可能でなければなりません(たとえば、適切なヘッダーを含める必要があります)。問題 1108 で、それ以外の方法で発生する可能性のあるエラーを確認します。
  • を使用する場合、デフォルト構築可能である必要があります。(後で説明するこの要件を回避する方法があります。
    get<your_type>()
    your_type
  • 関数では、関数 at() を使用して、ではなくオブジェクト値にアクセスします。キーが存在しない場合は、処理可能な例外をスローしますが、未定義の動作を示します。
    from_json
    operator[]
    at
    operator[]
  • 次のようなSTL型のシリアライザーやデシリアライザーを追加する必要はありません:ライブラリは既にこれらを実装しています。
    std::vector

マクロで生活をシンプルに

いくつかの構造体をシリアル化/逆シリアル化したいだけの場合は、/関数を多くの定型文にすることができます。

to_json
from_json

(1)JSONオブジェクトをシリアル化として使用し、(2)メンバー変数名をそのオブジェクトのオブジェクトキーとして使用する限り、作業を楽にする2つのマクロがあります。

  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...)
    は、コードを作成するクラス/構造体の名前空間内で定義されます。
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)
    は、コードを作成するクラス/構造体内で定義されます。このマクロは、プライベート メンバーにもアクセスできます。

どちらのマクロでも、最初のパラメーターはクラス/構造体の名前で、残りのすべてのパラメーターはメンバーの名前です。

上記の構造体の / 関数は、次のようにして作成できます。

to_json
from_json
person

namespace ns {
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)
}

必要に応じて、プライベートメンバーの例を次に示します。

NLOHMANN_DEFINE_TYPE_INTRUSIVE

namespace ns {
    class address {
      private:
        std::string street;
        int housenumber;
        int postcode;

      public:
        NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode)
    };
}

サードパーティのタイプを変換するにはどうすればよいですか?

これにはもう少し高度なテクニックが必要です。しかし、最初に、この変換メカニズムがどのように機能するかを見てみましょう。

ライブラリは JSON シリアライザーを使用して型を json に変換します。 の既定のシリアライザーは です (ADL は引数依存ルックアップを意味します)。

nlohmann::json
nlohmann::adl_serializer

次のように実装されます(簡略化されています)。

template <typename T>
struct adl_serializer {
    static void to_json(json& j, const T& value) {
        // calls the "to_json" method in T's namespace
    }

    static void from_json(const json& j, T& value) {
        // same thing, but with the "from_json" method
    }
};

このシリアライザーは、型の名前空間を制御できる場合に正常に動作します。しかし、または(C ++ 17)はどうですか?名前空間の乗っ取りはかなり悪いことであり、テンプレートの特殊化以外のものを追加することは違法です...

boost::optional
std::filesystem::path
boost
std

これを解決するには、名前空間に特殊化を追加する必要があります。

adl_serializer
nlohmann

// partial specialization (full specialization works too)
namespace nlohmann {
    template <typename T>
    struct adl_serializer<boost::optional<T>> {
        static void to_json(json& j, const boost::optional<T>& opt) {
            if (opt == boost::none) {
                j = nullptr;
            } else {
              j = *opt; // this will call adl_serializer<T>::to_json which will
                        // find the free function to_json in T's namespace!
            }
        }

        static void from_json(const json& j, boost::optional<T>& opt) {
            if (j.is_null()) {
                opt = boost::none;
            } else {
                opt = j.get<T>(); // same as above, but with
                                  // adl_serializer<T>::from_json
            }
        }
    };
}

デフォルト以外の構築可能/コピー不可能な型に使用するにはどうすればよいですか?
get()

あなたのタイプがMoveConstructibleであれば、方法があります。あなたも同様に専門化する必要がありますが、特別なオーバーロードがあります:

adl_serializer
from_json

struct move_only_type {
    move_only_type() = delete;
    move_only_type(int ii): i(ii) {}
    move_only_type(const move_only_type&) = delete;
    move_only_type(move_only_type&&) = default;

    int i;
};

namespace nlohmann {
    template <>
    struct adl_serializer<move_only_type> {
        // note: the return type is no longer 'void', and the method only takes
        // one argument
        static move_only_type from_json(const json& j) {
            return {j.get<int>()};
        }

        // Here's the catch! You must provide a to_json method! Otherwise, you
        // will not be able to convert move_only_type to json, since you fully
        // specialized adl_serializer on that type
        static void to_json(json& j, move_only_type t) {
            j = t.i;
        }
    };
}

独自のシリアライザーを作成できますか?(高度利用)

はい。テストスイートのunit-udt.cppを見て、いくつかの例を確認することをお勧めします。

独自のシリアライザーを作成する場合は、いくつかのことを行う必要があります。

  • 別のエイリアスを使用します (の最後のテンプレート パラメーターは
    basic_json
    nlohmann::json
    basic_json
    JSONSerializer
    )
  • すべての/メソッドでエイリアス(またはテンプレートパラメータ)を使用する
    basic_json
    to_json
    from_json
  • ADLを使用するときと必要なとき
    nlohmann::to_json
    nlohmann::from_json

次の例は、簡略化せずに、サイズ <= 32 の型のみを受け入れ、ADL を使用するものです。

// You should use void as a second template argument
// if you don't need compile-time checks on T
template<typename T, typename SFINAE = typename std::enable_if<sizeof(T) <= 32>::type>
struct less_than_32_serializer {
    template <typename BasicJsonType>
    static void to_json(BasicJsonType& j, T value) {
        // we want to use ADL, and call the correct to_json overload
        using nlohmann::to_json; // this method is called by adl_serializer,
                                 // this is where the magic happens
        to_json(j, value);
    }

    template <typename BasicJsonType>
    static void from_json(const BasicJsonType& j, T& value) {
        // same thing here
        using nlohmann::from_json;
        from_json(j, value);
    }
};

シリアライザを再実装するときは、注意を払わないとスタックオーバーフローが発生する可能性があります。

template <typename T, void>
struct bad_serializer
{
    template <typename BasicJsonType>
    static void to_json(BasicJsonType& j, const T& value) {
      // this calls BasicJsonType::json_serializer<T>::to_json(j, value);
      // if BasicJsonType::json_serializer == bad_serializer ... oops!
      j = value;
    }

    template <typename BasicJsonType>
    static void to_json(const BasicJsonType& j, T& value) {
      // this calls BasicJsonType::json_serializer<T>::from_json(j, value);
      // if BasicJsonType::json_serializer == bad_serializer ... oops!
      value = j.template get<T>(); // oops!
    }
};

列挙型変換の特化

既定では、列挙値は整数として JSON にシリアル化されます。場合によっては、これにより望ましくない動作が発生する可能性があります。データが JSON にシリアル化された後に列挙型が変更または並べ替えられた場合、後で逆シリアル化された JSON データは未定義であるか、当初の意図とは異なる列挙値になる可能性があります。

以下に示すように、特定の列挙型をJSONとの間でマッピングする方法をより正確に指定できます。

// example enum type declaration
enum TaskState {
    TS_STOPPED,
    TS_RUNNING,
    TS_COMPLETED,
    TS_INVALID=-1,
};

// map TaskState values to JSON as strings
NLOHMANN_JSON_SERIALIZE_ENUM( TaskState, {
    {TS_INVALID, nullptr},
    {TS_STOPPED, "stopped"},
    {TS_RUNNING, "running"},
    {TS_COMPLETED, "completed"},
})

マクロは、型の / 関数のセットを宣言しながら、繰り返しや定型シリアル化コードを回避します。

NLOHMANN_JSON_SERIALIZE_ENUM()
to_json()
from_json()
TaskState

使い:

// enum to JSON as string
json j = TS_STOPPED;
assert(j == "stopped");

// json string to enum
json j3 = "running";
assert(j3.get<TaskState>() == TS_RUNNING);

// undefined json value to enum (where the first map entry above is the default)
json jPi = 3.14;
assert(jPi.get<TaskState>() == TS_INVALID );

上記の任意の型変換と同様に、

  • NLOHMANN_JSON_SERIALIZE_ENUM()
    列挙型の名前空間(グローバル名前空間にすることができます)で宣言する必要があります、さもなければライブラリはそれを見つけることができず、デフォルトで整数シリアル化になります。
  • 変換を使用するすべての場所で利用可能でなければなりません(たとえば、適切なヘッダーを含める必要があります)。

その他の重要なポイント:

  • を使用する場合、未定義の JSON 値は、マップで指定された最初のペアにデフォルト設定されます。このデフォルトのペアは慎重に選択してください。
    get<ENUM_TYPE>()
  • マップで列挙型または JSON 値が複数回指定されている場合、JSON との間で変換するときに、マップの先頭から最初に一致したオカレンスが返されます。

バイナリ形式 (BSON、CBOR、MessagePack、UBJSON、および BJData)

JSONはユビキタスなデータ形式ですが、ネットワーク経由などのデータ交換に適した非常にコンパクトな形式ではありません。したがって、ライブラリはBSON(バイナリJSON)、CBOR(簡潔なバイナリオブジェクト表現)、メッセージパックUBJSON(ユニバーサルバイナリJSON仕様)、およびBJData(バイナリJData)をサポートして、JSON値をバイトベクトルに効率的にエンコードし、そのようなベクトルをデコードします。

// create a JSON value
json j = R"({"compact": true, "schema": 0})"_json;

// serialize to BSON
std::vector<std::uint8_t> v_bson = json::to_bson(j);

// 0x1B, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

// roundtrip
json j_from_bson = json::from_bson(v_bson);

// serialize to CBOR
std::vector<std::uint8_t> v_cbor = json::to_cbor(j);

// 0xA2, 0x67, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xF5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00

// roundtrip
json j_from_cbor = json::from_cbor(v_cbor);

// serialize to MessagePack
std::vector<std::uint8_t> v_msgpack = json::to_msgpack(j);

// 0x82, 0xA7, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xC3, 0xA6, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00

// roundtrip
json j_from_msgpack = json::from_msgpack(v_msgpack);

// serialize to UBJSON
std::vector<std::uint8_t> v_ubjson = json::to_ubjson(j);

// 0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D

// roundtrip
json j_from_ubjson = json::from_ubjson(v_ubjson);

このライブラリは、BSON、CBOR (バイト文字列)、およびメッセージパック (bin、ext、fixext) のバイナリ型もサポートしています。これらは、ライブラリの外部で処理されるようにデフォルトで保存されます。

std::vector<std::uint8_t>

// CBOR byte string with payload 0xCAFE
std::vector<std::uint8_t> v = {0x42, 0xCA, 0xFE};

// read value
json j = json::from_cbor(v);

// the JSON value has type binary
j.is_binary(); // true

// get reference to stored binary value
auto& binary = j.get_binary();

// the binary value has no subtype (CBOR has no binary subtypes)
binary.has_subtype(); // false

// access std::vector<std::uint8_t> member functions
binary.size(); // 2
binary[0]; // 0xCA
binary[1]; // 0xFE

// set subtype to 0x10
binary.set_subtype(0x10);

// serialize to MessagePack
auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE

サポートされているコンパイラ

すでに2022年ですが、C ++ 11のサポートはまだ少しまばらです。現在、次のコンパイラが動作することがわかっています。

  • GCC 4.8 - 12.0 (およびおそらくそれ以降)
  • Clang 3.4 - 15.0 (およびおそらくそれ以降)
  • Apple Clang 9.1 - 13.1 (そしておそらくそれ以降)
  • インテル C++ コンパイラ 17.0.2 (およびおそらくそれ以降)
  • Nvidia CUDA コンパイラ 11.0.221 (およびおそらくそれ以降)
  • Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (およびおそらくそれ以降)
  • Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (およびおそらくそれ以降)
  • Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (およびおそらくそれ以降)
  • Microsoft Visual C ++ 2022 /ビルドツール19.30.30709.0(およびおそらくそれ以降)

私は他のコンパイラ/バージョンについて学ぶことができてうれしいです。

ご注意:

  • GCC 4.8 にはバグ 57824): 複数行の生の文字列をマクロの引数にすることはできません。このコンパイラでは、複数行の生の文字列をマクロで直接使用しないでください。

  • Androidはデフォルトで非常に古いコンパイラとC ++ライブラリを使用します。これを修正するには、以下を .これにより、LLVM C ++ライブラリ、Clangコンパイラに切り替わり、C ++ 11およびデフォルトで無効になっているその他の機能が有効になります。

    Application.mk

    APP_STL := c++_shared
    NDK_TOOLCHAIN_VERSION := clang3.6
    APP_CPPFLAGS += -frtti -fexceptions
    

    このコードは、Android NDK リビジョン 9 - 11 (およびおそらくそれ以降) および CrystaX の Android NDK バージョン 10 で正常にコンパイルされます。

  • MinGW または Android SDK で実行されている GCC の場合、エラー (または同様に、 または ) が発生する可能性があります。これはコードの問題ではなく、コンパイラ自体の問題であることに注意してください。Android では、新しい環境でビルドするには、上記を参照してください。MinGWについては、このバグを修正する方法については、このサイトこのディスカッションを参照してください。Android NDK を使用する場合は、こちらのディスカッションを参照してください。

    'to_string' is not a member of 'std'
    strtod
    strtof
    APP_STL := gnustl_static

  • サポートされていないバージョンのGCCとClangは、ディレクティブによって拒否されます。これは、を定義することでオフに切り替えることができます。この場合、サポートは期待できないことに注意してください。

    #error
    JSON_SKIP_UNSUPPORTED_COMPILER_CHECK

次のコンパイラは現在、AppVeyorDrone CI、および GitHub Actions の継続的インテグレーションで使用されています。

コンパイラ オペレーティング システム CI プロバイダー
アップルクラン11.0.3(クラン-1103.0.32.62);Xcode 11.7 macOS 11.7.1 GitHub Actions
アップルクラン12.0.0(クラン-1200.0.32.29);Xcode 12.4 macOS 11.7.1 GitHub Actions
アップルクラン12.0.5(クラン-1205.0.22.11);Xcode 12.5.1 macOS 11.7.1 GitHub Actions
アップルクラン13.0.0(クラン-1300.0.29.3);Xcode 13.0 macOS 11.7.1 GitHub Actions
アップルクラン13.0.0(クラン-1300.0.29.3);Xcode 13.1 macOS 12.6.1 GitHub Actions
アップルクラン13.0.0(クラン-1300.0.29.30);Xcode 13.2.1 macOS 12.6.1 GitHub Actions
アップルクラン13.1.6(クラン-1316.0.21.2.3);Xcode 13.3.1 macOS 12.6.1 GitHub Actions
アップルクラン13.1.6(クラン-1316.0.21.2.5);Xcode 13.4.1 macOS 12.6.1 GitHub Actions
アップルクラン14.0.0(クラン-1400.0.29.102);Xcode 14.0 macOS 12.6.1 GitHub Actions
アップルクラン14.0.0(クラン-1400.0.29.102);Xcode 14.0.1 macOS 12.6.1 GitHub Actions
アップルクラン14.0.0(クラン-1400.0.29.202);Xcode 14.1 macOS 12.6.1 GitHub Actions
クラン3.5.2 ウブンツ 20.04.3 LTS GitHub Actions
クラン3.6.2 ウブンツ 20.04.3 LTS GitHub Actions
クラン3.7.1 ウブンツ 20.04.3 LTS GitHub Actions
クラン3.8.1 ウブンツ 20.04.3 LTS GitHub Actions
クラン3.9.1 ウブンツ 20.04.3 LTS GitHub Actions
クラン4.0.1 ウブンツ 20.04.3 LTS GitHub Actions
クラン5.0.2 ウブンツ 20.04.3 LTS GitHub Actions
クラン6.0.1 ウブンツ 20.04.3 LTS GitHub Actions
クラン7.0.1 ウブンツ 20.04.3 LTS GitHub Actions
クラン8.0.0 ウブンツ 20.04.3 LTS GitHub Actions
クラン9.0.0 ウブンツ 20.04.3 LTS GitHub Actions
クラン10.0.0 ウブンツ 20.04.3 LTS GitHub Actions
GNUライクなコマンドラインで10.0.0を鳴らす ウィンドウズ-10.0.17763 GitHub Actions
GNUライクなコマンドラインで11.0.0を鳴らす ウィンドウズ-10.0.17763 GitHub Actions
MSVCのようなコマンドラインで11.0.0を鳴らす ウィンドウズ-10.0.17763 GitHub Actions
クラン11.0.0 ウブンツ 20.04.3 LTS GitHub Actions
クラン12.0.0 ウブンツ 20.04.3 LTS GitHub Actions
クラン13.0.0 ウブンツ 20.04.3 LTS GitHub Actions
クラン14.0.0 ウブンツ 20.04.3 LTS GitHub Actions
クラン15.0.4 ウブンツ 20.04.3 LTS GitHub Actions
Clang 16.0.0 (16.0.0-++20221031071727+500876226c60-1exp120221031071831.439) ウブンツ 20.04.3 LTS GitHub Actions
GCC 4.8.5 (Ubuntu 4.8.5-4ubuntu2) ウブンツ 20.04.3 LTS GitHub Actions
GCC 4.9.4 ウブンツ 20.04.3 LTS GitHub Actions
GCC 5.5.0 ウブンツ 20.04.3 LTS GitHub Actions
GCC 6.5.0 ウブンツ 20.04.3 LTS GitHub Actions
GCC 7.5.0 ウブンツ 20.04.3 LTS GitHub Actions
GCC 8.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project) ウィンドウズ-10.0.17763 GitHub Actions
GCC 8.1.0 (x86_64-posix-she-rev0, MinGW-W64 プロジェクトによって構築) ウィンドウズ-10.0.17763 GitHub Actions
GCC 8.5.0 ウブンツ 20.04.3 LTS GitHub Actions
GCC 9.5.0 ウブンツ 20.04.3 LTS GitHub Actions
GCC 10.4.0 ウブンツ 20.04.3 LTS GitHub Actions
GCC 11.1.0 Ubuntu (aarch64) ドローンCI
GCC 11.3.0 ウブンツ 20.04.3 LTS GitHub Actions
GCC 12.2.0 ウブンツ 20.04.3 LTS GitHub Actions
GCC 13.0.0 20220605 (実験的) ウブンツ 20.04.3 LTS GitHub Actions
インテルC ++コンパイラ2021.5.0.20211109 ウブンツ 20.04.3 LTS GitHub Actions
NVCC 11.0.221 ウブンツ 20.04.3 LTS GitHub Actions
Visual Studio 14 2015 MSVC 19.0.24241.7 (ビルド エンジン バージョン 14.0.25420.1) ウィンドウズ-6.3.9600 AppVeyor
Visual Studio 15 2017 MSVC 19.16.27035.0 (ビルド エンジン バージョン 15.9.21+g9802d43bc3 for .NET Framework ) ウィンドウズ-10.0.14393 AppVeyor
Visual Studio 16 2019 MSVC 19.28.29912.0 (ビルド エンジン バージョン 16.9.0+57a23d249 for .NET Framework ) ウィンドウズ-10.0.17763 GitHub Actions
Visual Studio 16 2019 MSVC 19.28.29912.0 (ビルド エンジン バージョン 16.9.0+57a23d249 for .NET Framework ) ウィンドウズ-10.0.17763 AppVeyor
Visual Studio 17 2022 MSVC 19.30.30709.0 (.NET Framework 用のビルド エンジン バージョン 17.0.31804.368) ウィンドウズ-10.0.20348 GitHub Actions

統合

json.hpp は、ここで、またはここでリリースされる唯一の必須ファイルです。追加する必要があります

single_include/nlohmann

#include <nlohmann/json.hpp>

// for convenience
using json = nlohmann::json;

JSONを処理し、C ++ 11を有効にするために必要なスイッチを設定します(GCCやClangなど)。

-std=c++11

さらに、ファイルインクルード/nlohmann/json_fwd.hpp を前方宣言に使用することもできます。json_fwd.hpp のインストール (cmake のインストール手順の一部として) は、.

-DJSON_MultipleHeaders=ON

CMake

CMake でインターフェイス ターゲットを使用することもできます。このターゲットは、適切なインクルード ディレクトリを指すための適切な使用要件と、必要な C++11 フラグを設定します。

nlohmann_json::nlohmann_json
INTERFACE_INCLUDE_DIRECTORIES
INTERFACE_COMPILE_FEATURES

CMake プロジェクトからこのライブラリを使用するには、生成されたパッケージ構成から名前空間付きのインポートされたターゲットを使用して直接検索し、使用できます。

find_package()

# CMakeLists.txt
find_package(nlohmann_json 3.2.0 REQUIRED)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)

パッケージ構成ファイル は、インストールツリーから使用することも、ビルドツリーから直接使用することもできます。

nlohmann_jsonConfig.cmake

埋め込み

ライブラリを既存のCMakeプロジェクトに直接埋め込むには、ソースツリー全体をサブディレクトリに配置し、ファイルを呼び出します。

add_subdirectory()
CMakeLists.txt

# Typically you don't care so much for a third party library's tests to be
# run from your own project's code.
set(JSON_BuildTests OFF CACHE INTERNAL "")

# If you only include this third party in PRIVATE source files, you do not
# need to install it when your main project gets installed.
# set(JSON_Install OFF CACHE INTERNAL "")

# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
# unintended consequences that will break the build.  It's generally
# discouraged (although not necessarily well documented as such) to use
# include(...) for pulling in other CMake projects anyways.
add_subdirectory(nlohmann_json)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
埋め込み (フェッチコンテンツ)

CMake v3.11以降、フェッチコンテンツは 構成時にリリースを依存関係として自動的にダウンロードするために使用されます。

例:

include(FetchContent)

FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz)
FetchContent_MakeAvailable(json)

target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)

: バージョン 3.10.0 以降でサポートされている上記の URL アプローチを使用することをお勧めします。詳細については、https://json.nlohmann.me/integration/cmake/#fetchcontent を参照してください。

両方をサポート

プロジェクトで外部提供の JSON ライブラリまたは埋め込み JSON ライブラリをサポートできるようにするには、次のようなパターンを使用できます。

# Top level CMakeLists.txt
project(FOO)
...
option(FOO_USE_EXTERNAL_JSON "Use an external JSON library" OFF)
...
add_subdirectory(thirdparty)
...
add_library(foo ...)
...
# Note that the namespaced target will always be available regardless of the
# import method
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
# thirdparty/CMakeLists.txt
...
if(FOO_USE_EXTERNAL_JSON)
  find_package(nlohmann_json 3.2.0 REQUIRED)
else()
  set(JSON_BuildTests OFF CACHE INTERNAL "")
  add_subdirectory(nlohmann_json)
endif()
...

thirdparty/nlohmann_json
は、このソースツリーの完全なコピーです。

パッケージマネージャー

🍺OS Xと自作を使用している場合は、入力するだけで設定されます。最新リリースではなく最先端が必要な場合は、 を使用します。詳細については、nlohmann-json を参照してください。

brew install nlohmann-json
brew install nlohmann-json --HEAD

中間子ビルドシステムを使用している場合は、このソースツリーを中間子サブプロジェクトとして追加します。また、このプロジェクトのリリースで公開されているものを使用して、ベンダー化されたソースツリーのサイズを小さくすることもできます。または、Meson WrapDBからラップファイルをダウンロードして取得するか、単に.パッケージに関する問題については、中間子プロジェクトを参照してください。

include.zip
meson wrap install nlohmann_json

提供されているものは、システム全体にインストールするためのCMakeの代替としても使用できますが、その場合、pkg-configファイルがインストールされます。これを使用するには、ビルドシステムにpkg-config依存関係を要求させるだけです。中間子では、サブプロジェクトを直接使用するよりも、サブプロジェクトのフォールバックでdependency()オブジェクトを使用することをお勧めします。

meson.build
nlohmann_json
nlohmann_json

Bazel を使用している場合は、単に またはを使用してこのリポジトリを参照し、 に依存することができます。

http_archive
git_repository
@nlohmann_json//:json

Conanを使用して依存関係を管理している場合は、nlohmann_json / x.y.zを要件に追加するだけで、使用するリリースバージョンはどこにありますか。パッケージで問題が発生した場合は、ここで問題を報告してください。

conanfile
x.y.z

Spack を使用して依存関係を管理している場合は、nlohmann-json パッケージを使用できます。パッケージに関する問題については、spackプロジェクトを参照してください。

プロジェクトで外部依存関係にハンターを使用している場合は、nlohmann_jsonパッケージを使用できます。パッケージに関する問題については、ハンタープロジェクトを参照してください。

Buckarooを使用している場合は、このライブラリのモジュールをでインストールできます。ここで問題を報告してください。ここにデモリポジトリがあります。

buckaroo add github.com/buckaroo-pm/nlohmann-json

プロジェクトで外部依存関係にvcpkgを使用している場合は、nlohmann-jsonパッケージをインストールし、表示される説明に従うことができます。パッケージに関する問題については、vcpkg プロジェクトを参照してください。

vcpkg install nlohmann-json

cgetを使用している場合は、を使用して最新の開発バージョンをインストールできます。特定のバージョンは、 を使用してインストールできます。また、複数のヘッダーバージョンは、フラグを追加することでインストールできます(つまり、)。

cget install nlohmann/json
cget install nlohmann/json@v3.1.0
-DJSON_MultipleHeaders=ON
cget install nlohmann/json -DJSON_MultipleHeaders=ON

CocoaPodsを使用している場合は、ポッドファイルをポッドファイルに追加することでライブラリを使用できます(を参照)。ここで問題を報告してください。

"nlohmann_json", '~>3.1.2'

NuGet を使用している場合は、パッケージ nlohmann.json を使用できます。パッケージの使用方法については、この詳細な説明を確認してください。ここで問題を報告してください。

condaを使用している場合は、 conda-forge の実行からnlohmann_jsonパッケージを使用できます。ここで問題を報告してください。

conda install -c conda-forge nlohmann_json

MSYS2 を使用している場合は、mingw-w64-nlohmann-json パッケージを、入力するか、インストールするだけで使用できます。パッケージで問題が発生した場合は、ここで問題を報告してください。

pacman -S mingw-w64-i686-nlohmann-json
pacman -S mingw-w64-x86_64-nlohmann-json

MacPorts を使用している場合は、実行して nlohmann-json パッケージをインストールします。

sudo port install nlohmann-json

build2 を使用している場合は、パブリックリポジトリ https://cppget.org から、またはパッケージのソースリポジトリから直接 nlohmann-json パッケージを使用できます。プロジェクトのファイルに、(おそらくいくつかのバージョンの制約があります)追加するだけです。での依存関係の使用に慣れていない場合は、この概要をお読みください。 パッケージで問題が発生した場合は、ここで問題を報告してください。

manifest
depends: nlohmann-json
build2

wsjcpp を使用している場合は、このコマンドを使用して最新バージョンを取得できます。ブランチ ":d evelop" を既存のタグまたは別のブランチに変更できます。

wsjcpp install "https://github.com/nlohmann/json:develop"

CPM.cmakeを使用している場合は、この例を確認できます。プロジェクトにCPMスクリプトを追加した後、CMakeに次のスニペットを実装します。

CPMAddPackage(
    NAME nlohmann_json
    GITHUB_REPOSITORY nlohmann/json
    VERSION 3.9.1)

Pkg-config

ベア Makefiles を使用している場合は、 を使用して、ライブラリがインストールされている場所を指すインクルード フラグを生成できます。

pkg-config

pkg-config nlohmann_json --cflags

Users of the Meson build system will also be able to use a system-wide library, which will be found by :

pkg-config

json = dependency('nlohmann_json', required: true)

License

The class is licensed under the MIT License:

Copyright © 2013-2022 Niels Lohmann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the MIT License (see above). Copyright © 2008-2009 Björn Hoehrmann bjoern@hoehrmann.de

The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the MIT License (see above). Copyright © 2009 Florian Loitsch

The class contains a copy of Hedley from Evan Nemerson which is licensed as CC0-1.0.

The class contains parts of Google Abseil which is licensed under the Apache 2.0 License.

Contact

If you have questions regarding the library, I would like to invite you to open an issue at GitHub. Please describe your request, problem, or question as detailed as possible, and also mention the version of the library you are using as well as the version of your compiler and operating system. Opening an issue at GitHub allows other users and contributors to this library to collaborate. For instance, I have little experience with MSVC, and most issues in this regard have been solved by a growing community. If you have a look at the closed issues, you will see that we react quite timely in most cases.

Only if your request would contain confidential information, please send me an email. For encrypted messages, please use this key.

Security

Commits by Niels Lohmann and releases are signed with this PGP Key.

Thanks

I deeply appreciate the help of the following people.

  1. Teemperor implemented CMake support and lcov integration, realized escape and Unicode handling in the string parser, and fixed the JSON serialization.
  2. elliotgoodrich fixed an issue with double deletion in the iterator classes.
  3. kirkshoop made the iterators of the class composable to other libraries.
  4. wancw fixed a bug that hindered the class to compile with Clang.
  5. Tomas Åblad found a bug in the iterator implementation.
  6. Joshua C. Randall fixed a bug in the floating-point serialization.
  7. Aaron Burghardt implemented code to parse streams incrementally. Furthermore, he greatly improved the parser class by allowing the definition of a filter function to discard undesired elements while parsing.
  8. Daniel Kopeček fixed a bug in the compilation with GCC 5.0.
  9. Florian Weber fixed a bug in and improved the performance of the comparison operators.
  10. Eric Cornelius pointed out a bug in the handling with NaN and infinity values. He also improved the performance of the string escaping.
  11. 易思龙 implemented a conversion from anonymous enums.
  12. kepkin patiently pushed forward the support for Microsoft Visual studio.
  13. gregmarr simplified the implementation of reverse iterators and helped with numerous hints and improvements. In particular, he pushed forward the implementation of user-defined types.
  14. Caio Luppi fixed a bug in the Unicode handling.
  15. dariomt fixed some typos in the examples.
  16. Daniel Frey cleaned up some pointers and implemented exception-safe memory allocation.
  17. Colin Hirsch took care of a small namespace issue.
  18. Huu Nguyen correct a variable name in the documentation.
  19. Silverweed overloaded to accept an rvalue reference.
    parse()
  20. dariomt fixed a subtlety in MSVC type support and implemented the function to get a reference to stored values.
    get_ref()
  21. ZahlGraf added a workaround that allows compilation using Android NDK.
  22. whackashoe replaced a function that was marked as unsafe by Visual Studio.
  23. 406345 fixed two small warnings.
  24. Glen Fernandes noted a potential portability problem in the function.
    has_mapped_type
  25. Corbin Hughes fixed some typos in the contribution guidelines.
  26. twelsby fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers and implemented better roundtrip support for parsed numbers.
  27. Volker Diels-Grabsch fixed a link in the README file.
  28. msm- added support for American Fuzzy Lop.
  29. Annihil fixed an example in the README file.
  30. Themercee noted a wrong URL in the README file.
  31. Lv Zheng fixed a namespace issue with and .
    int64_t
    uint64_t
  32. abc100m analyzed the issues with GCC 4.8 and proposed a partial solution.
  33. zewt added useful notes to the README file about Android.
  34. Róbert Márki added a fix to use move iterators and improved the integration via CMake.
  35. Chris Kitching cleaned up the CMake files.
  36. Tom Needham fixed a subtle bug with MSVC 2015 which was also proposed by Michael K..
  37. Mário Feroldi fixed a small typo.
  38. duncanwerner found a really embarrassing performance regression in the 2.0.0 release.
  39. Damien fixed one of the last conversion warnings.
  40. Thomas Braun fixed a warning in a test case and adjusted MSVC calls in the CI.
  41. Théo DELRIEU patiently and constructively oversaw the long way toward iterator-range parsing. He also implemented the magic behind the serialization/deserialization of user-defined types and split the single header file into smaller chunks.
  42. Stefan fixed a minor issue in the documentation.
  43. Vasil Dimov fixed the documentation regarding conversions from .
    std::multiset
  44. ChristophJud overworked the CMake files to ease project inclusion.
  45. Vladimir Petrigo made a SFINAE hack more readable and added Visual Studio 17 to the build matrix.
  46. Denis Andrejew fixed a grammar issue in the README file.
  47. Pierre-Antoine Lacaze found a subtle bug in the function.
    dump()
  48. TurpentineDistillery pointed to
    std::locale::classic()
    to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing.
  49. cgzones had an idea how to fix the Coverity scan.
  50. Jared Grubb silenced a nasty documentation warning.
  51. Yixin Zhang fixed an integer overflow check.
  52. Bosswestfalen merged two iterator classes into a smaller one.
  53. Daniel599 helped to get Travis execute the tests with Clang's sanitizers.
  54. Jonathan Lee fixed an example in the README file.
  55. gnzlbg supported the implementation of user-defined types.
  56. Alexej Harm helped to get the user-defined types working with Visual Studio.
  57. Jared Grubb supported the implementation of user-defined types.
  58. EnricoBilla noted a typo in an example.
  59. Martin Hořeňovský found a way for a 2x speedup for the compilation time of the test suite.
  60. ukhegg found proposed an improvement for the examples section.
  61. rswanson-ihi noted a typo in the README.
  62. Mihai Stan fixed a bug in the comparison with s.
    nullptr
  63. Tushar Maheshwari added cotire support to speed up the compilation.
  64. TedLyngmo noted a typo in the README, removed unnecessary bit arithmetic, and fixed some warnings.
    -Weffc++
  65. Krzysztof Woś made exceptions more visible.
  66. ftillier fixed a compiler warning.
  67. tinloaf made sure all pushed warnings are properly popped.
  68. Fytch found a bug in the documentation.
  69. Jay Sistar implemented a Meson build description.
  70. Henry Lee fixed a warning in ICC and improved the iterator implementation.
  71. Vincent Thiery maintains a package for the Conan package manager.
  72. Steffen fixed a potential issue with MSVC and .
    std::min
  73. Mike Tzou fixed some typos.
  74. amrcode noted a misleading documentation about comparison of floats.
  75. Oleg Endo reduced the memory consumption by replacing with .
    <iostream>
    <iosfwd>
  76. dan-42 cleaned up the CMake files to simplify including/reusing of the library.
  77. Nikita Ofitserov allowed for moving values from initializer lists.
  78. Greg Hurrell fixed a typo.
  79. Dmitry Kukovinets fixed a typo.
  80. kbthomp1 fixed an issue related to the Intel OSX compiler.
  81. Markus Werle fixed a typo.
  82. WebProdPP fixed a subtle error in a precondition check.
  83. Alex noted an error in a code sample.
  84. Tom de Geus reported some warnings with ICC and helped to fix them.
  85. Perry Kundert simplified reading from input streams.
  86. Sonu Lohani fixed a small compilation error.
  87. Jamie Seward fixed all MSVC warnings.
  88. Nate Vargas added a Doxygen tag file.
  89. pvleuven helped to fix a warning in ICC.
  90. Pavel helped to fix some warnings in MSVC.
  91. Jamie Seward avoided unnecessary string copies in and .
    find()
    count()
  92. Mitja fixed some typos.
  93. Jorrit Wronski updated the Hunter package links.
  94. Matthias Möller added a for the MSVC debug view.
    .natvis
  95. bogemic fixed some C++17 deprecation warnings.
  96. Eren Okka fixed some MSVC warnings.
  97. abolz integrated the Grisu2 algorithm for proper floating-point formatting, allowing more roundtrip checks to succeed.
  98. Vadim Evard fixed a Markdown issue in the README.
  99. zerodefect fixed a compiler warning.
  100. Kert allowed to template the string type in the serialization and added the possibility to override the exceptional behavior.
  101. mark-99 helped fixing an ICC error.
  102. Patrik Huber fixed links in the README file.
  103. johnfb found a bug in the implementation of CBOR's indefinite length strings.
  104. Paul Fultz II added a note on the cget package manager.
  105. Wilson Lin made the integration section of the README more concise.
  106. RalfBielig detected and fixed a memory leak in the parser callback.
  107. agrianius allowed to dump JSON to an alternative string type.
  108. Kevin Tonon overworked the C++11 compiler checks in CMake.
  109. Axel Huebl simplified a CMake check and added support for the Spack package manager.
  110. Carlos O'Ryan fixed a typo.
  111. James Upjohn fixed a version number in the compilers section.
  112. Chuck Atkins adjusted the CMake files to the CMake packaging guidelines and provided documentation for the CMake integration.
  113. Jan Schöppach fixed a typo.
  114. martin-mfg fixed a typo.
  115. Matthias Möller removed the dependency from .
    std::stringstream
  116. agrianius added code to use alternative string implementations.
  117. Daniel599 allowed to use more algorithms with the function.
    items()
  118. Julius Rakow fixed the Meson include directory and fixed the links to cppreference.com.
  119. Sonu Lohani fixed the compilation with MSVC 2015 in debug mode.
  120. grembo fixed the test suite and re-enabled several test cases.
  121. Hyeon Kim introduced the macro to control the exception handling inside the library.
    JSON_INTERNAL_CATCH
  122. thyu fixed a compiler warning.
  123. David Guthrie fixed a subtle compilation error with Clang 3.4.2.
  124. Dennis Fischer allowed to call without installing the library.
    find_package
  125. Hyeon Kim fixed an issue with a double macro definition.
  126. Ben Berman made some error messages more understandable.
  127. zakalibit fixed a compilation problem with the Intel C++ compiler.
  128. mandreyel fixed a compilation problem.
  129. Kostiantyn Ponomarenko added version and license information to the Meson build file.
  130. Henry Schreiner added support for GCC 4.8.
  131. knilch made sure the test suite does not stall when run in the wrong directory.
  132. Antonio Borondo fixed an MSVC 2017 warning.
  133. Dan Gendreau implemented the macro to quickly define an enum/JSON mapping.
    NLOHMANN_JSON_SERIALIZE_ENUM
  134. efp added line and column information to parse errors.
  135. julian-becker added BSON support.
  136. Pratik Chowdhury added support for structured bindings.
  137. David Avedissian added support for Clang 5.0.1 (PS4 version).
  138. Jonathan Dumaresq implemented an input adapter to read from .
    FILE*
  139. kjpus fixed a link in the documentation.
  140. Manvendra Singh fixed a typo in the documentation.
  141. ziggurat29 fixed an MSVC warning.
  142. Sylvain Corlay added code to avoid an issue with MSVC.
  143. mefyl fixed a bug when JSON was parsed from an input stream.
  144. Millian Poquet allowed to install the library via Meson.
  145. Michael Behrns-Miller found an issue with a missing namespace.
  146. Nasztanovics Ferenc fixed a compilation issue with libc 2.12.
  147. Andreas Schwab fixed the endian conversion.
  148. Mark-Dunning fixed a warning in MSVC.
  149. Gareth Sylvester-Bradley added for JSON Pointers.
    operator/
  150. John-Mark noted a missing header.
  151. Vitaly Zaitsev fixed compilation with GCC 9.0.
  152. Laurent Stacul fixed compilation with GCC 9.0.
  153. Ivor Wanders helped to reduce the CMake requirement to version 3.1.
  154. njlr updated the Buckaroo instructions.
  155. Lion fixed a compilation issue with GCC 7 on CentOS.
  156. Isaac Nickaein improved the integer serialization performance and implemented the function.
    contains()
  157. past-due suppressed an unfixable warning.
  158. Elvis Oric improved Meson support.
  159. Matěj Plch fixed an example in the README.
  160. Mark Beckwith fixed a typo.
  161. scinart fixed bug in the serializer.
  162. Patrick Boettcher implemented and for JSON Pointers.
    push_back()
    pop_back()
  163. Bruno Oliveira added support for Conda.
  164. Michele Caini fixed links in the README.
  165. Hani documented how to install the library with NuGet.
  166. Mark Beckwith fixed a typo.
  167. yann-morin-1998 helped to reduce the CMake requirement to version 3.1.
  168. Konstantin Podsvirov maintains a package for the MSYS2 software distro.
  169. remyabel added GNUInstallDirs to the CMake files.
  170. Taylor Howard fixed a unit test.
  171. Gabe Ron implemented the method.
    to_string
  172. Watal M. Iwasaki fixed a Clang warning.
  173. Viktor Kirilov switched the unit tests from Catch to doctest
  174. Juncheng E fixed a typo.
  175. tete17 fixed a bug in the function.
    contains
  176. Xav83 fixed some cppcheck warnings.
  177. 0xflotus fixed some typos.
  178. Christian Deneke added a const version of .
    json_pointer::back
  179. Julien Hamaide made the function work with custom string types.
    items()
  180. Evan Nemerson updated fixed a bug in Hedley and updated this library accordingly.
  181. Florian Pigorsch fixed a lot of typos.
  182. Camille Bégué fixed an issue in the conversion from and to .
    std::pair
    std::tuple
    json
  183. Anthony VH fixed a compile error in an enum deserialization.
  184. Yuriy Vountesmery noted a subtle bug in a preprocessor check.
  185. Chen fixed numerous issues in the library.
  186. Antony Kellermann added a CI step for GCC 10.1.
  187. Alex fixed an MSVC warning.
  188. Rainer proposed an improvement in the floating-point serialization in CBOR.
  189. Francois Chabot made performance improvements in the input adapters.
  190. Arthur Sonzogni documented how the library can be included via .
    FetchContent
  191. Rimas Misevičius fixed an error message.
  192. Alexander Myasnikov fixed some examples and a link in the README.
  193. Hubert Chathi made CMake's version config file architecture-independent.
  194. OmnipotentEntity implemented the binary values for CBOR, MessagePack, BSON, and UBJSON.
  195. ArtemSarmini fixed a compilation issue with GCC 10 and fixed a leak.
  196. Evgenii Sopov integrated the library to the wsjcpp package manager.
  197. Sergey Linev fixed a compiler warning.
  198. Miguel Magalhães fixed the year in the copyright.
  199. Gareth Sylvester-Bradley fixed a compilation issue with MSVC.
  200. Alexander “weej” Jones fixed an example in the README.
  201. Antoine Cœur fixed some typos in the documentation.
  202. jothepro updated links to the Hunter package.
  203. Dave Lee fixed link in the README.
  204. Joël Lamotte added instruction for using Build2's package manager.
  205. Paul Jurczak fixed an example in the README.
  206. Sonu Lohani fixed a warning.
  207. Carlos Gomes Martinho updated the Conan package source.
  208. Konstantin Podsvirov fixed the MSYS2 package documentation.
  209. Tridacnid improved the CMake tests.
  210. Michael fixed MSVC warnings.
  211. Quentin Barbarat fixed an example in the documentation.
  212. XyFreak fixed a compiler warning.
  213. TotalCaesar659 fixed links in the README.
  214. Tanuj Garg improved the fuzzer coverage for UBSAN input.
  215. AODQ fixed a compiler warning.
  216. jwittbrodt made inline.
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
  217. pfeatherstone improved the upper bound of arguments of the / macros.
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
    NLOHMANN_DEFINE_TYPE_INTRUSIVE
  218. Jan Procházka fixed a bug in the CBOR parser for binary and string values.
  219. T0b1-iOS fixed a bug in the new hash implementation.
  220. Matthew Bauer adjusted the CBOR writer to create tags for binary subtypes.
  221. gatopeich implemented an ordered map container for .
    nlohmann::ordered_json
  222. Érico Nogueira Rolim added support for pkg-config.
  223. KonanM proposed an implementation for the / macros.
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
    NLOHMANN_DEFINE_TYPE_INTRUSIVE
  224. Guillaume Racicot implemented support and allowed C++20 support.
    string_view
  225. Alex Reinking improved CMake support for .
    FetchContent
  226. Hannes Domani provided a GDB pretty printer.
  227. Lars Wirzenius reviewed the README file.
  228. Jun Jie fixed a compiler path in the CMake scripts.
  229. Ronak Buch fixed typos in the documentation.
  230. Alexander Karzhenkov fixed a move constructor and the Travis builds.
  231. Leonardo Lima added CPM.Cmake support.
  232. Joseph Blackman fixed a warning.
  233. Yaroslav updated doctest and implemented unit tests.
  234. Martin Stump fixed a bug in the CMake files.
  235. Jaakko Moisio fixed a bug in the input adapters.
  236. bl-ue fixed some Markdown issues in the README file.
  237. William A. Wieselquist fixed an example from the README.
  238. abbaswasim fixed an example from the README.
  239. Remy Jette fixed a warning.
  240. Fraser fixed the documentation.
  241. Ben Beasley updated doctest.
  242. Doron Behar fixed pkg-config.pc.
  243. raduteo fixed a warning.
  244. David Pfahler added the possibility to compile the library without I/O support.
  245. Morten Fyhn Amundsen fixed a typo.
  246. jpl-mac allowed to treat the library as a system header in CMake.
  247. Jason Dsouza fixed the indentation of the CMake file.
  248. offa added a link to Conan Center to the documentation.
  249. TotalCaesar659 updated the links in the documentation to use HTTPS.
  250. Rafail Giavrimis fixed the Google Benchmark default branch.
  251. Louis Dionne fixed a conversion operator.
  252. justanotheranonymoususer made the examples in the README more consistent.
  253. Finkman suppressed some warnings.
    -Wfloat-equal
  254. Ferry Huberts fixed warnings.
    -Wswitch-enum
  255. Arseniy Terekhin made the GDB pretty-printer robust against unset variable names.
  256. Amir Masoud Abdol updated the Homebrew command as nlohmann/json is now in homebrew-core.
  257. Hallot fixed some .
    -Wextra-semi-stmt warnings
  258. Giovanni Cerretani fixed warnings on .
    -Wunused
    JSON_DIAGNOSTICS
  259. Bogdan Popescu hosts the docset for offline documentation viewers.
  260. Carl Smedstad fixed an assertion error when using .
    JSON_DIAGNOSTICS
  261. miikka75 provided an important fix to compile C++17 code with Clang 9.
  262. Maarten Becker fixed a warning for shadowed variables.
  263. Cristi Vîjdea fixed typos in the documentation.
    operator[]
  264. Alex Beregszaszi fixed spelling mistakes in comments.
  265. Dirk Stolle fixed typos in documentation.
  266. Daniel Albuschat corrected the parameter name in the documentation.
    parse
  267. Prince Mendiratta fixed a link to the FAQ.
  268. Florian Albrechtskirchinger implemented support for object keys and made dozens of other improvements.
    std::string_view
  269. Qianqian Fang implemented the Binary JData (BJData) format.
  270. pketelsen added macros and .
    NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT
  271. DarkZeros adjusted to code to not clash with Arduino defines.
  272. flagarde fixed the output of for MSVC.
    meta()
  273. Giovanni Cerretani fixed a check for .
    std::filesystem
  274. Dimitris Apostolou fixed a typo.
  275. Ferry Huberts fixed a typo.
  276. Michael Nosthoff fixed a typo.
  277. JungHoon Lee fixed a typo.
  278. Faruk D. fixed the CITATION.CFF file.
  279. Andrea Cocito added a clarification on macro usage to the documentation.
  280. Krzysiek Karbowiak refactored the tests to use .
    CHECK_THROWS_WITH_AS
  281. Chaoqi Zhang fixed a typo.
  282. ivanovmp fixed a whitespace error.
  283. KsaNL fixed a build error when including .
    <windows.h>
  284. Andrea Pappacoda moved and files to directory.
    .pc
    .cmake
    share
  285. Wolf Vollprecht added the function.
    patch_inplace
  286. Jake Zimmerman highlighted common usage patterns in the README file.
  287. NN added the Visual Studio output directory to .
    .gitignore
  288. Romain Reignier improved the performance the vector output adapter.
  289. Mike fixed the .
    std::iterator_traits
  290. Richard Hozák added macro to disable default enum conversions.
    JSON_NO_ENUM
  291. vakokako fixed tests when compiling with C++20.
  292. Alexander “weej” Jones fixed an example in the README.
  293. Eli Schwartz added more files to the archive.
    include.zip
  294. Kevin Lu fixed a compilation issue when typedefs with certain names were present.
  295. Trevor Hickey improved the description of an example.
  296. Jef LeCompte updated the year in the README file.
  297. Alexandre Hamez fixed a warning.
  298. Maninderpal Badhan fixed a typo.
  299. kevin-- added a note to an example in the README file.
  300. I fixed a typo.
  301. Gregorio Litenstein fixed the Clang detection.
  302. Andreas Smas added a Doozer badge.
  303. WanCW fixed the string conversion with Clang.
  304. zhaohuaxishi fixed a Doxygen error.
  305. emvivre removed an invalid parameter from CMake.
  306. Tobias Hermann fixed a link in the README file.
  307. Michael fixed a warning.
  308. Ryan Mulder added to the function.
    ensure_ascii
    dump
  309. Muri Nicanor fixed the discovery in the Makefile.
    sed
  310. David Avedissian implemented SFINAE-friendly .
    iterator_traits
  311. AQNOUCH Mohammed fixed a typo in the README.
  312. Gareth Sylvester-Bradley added and to construct JSON pointers.
    operator/=
    operator/
  313. Michael Macnair added support for afl-fuzz testing.
  314. Berkus Decker fixed a typo in the README.
  315. Illia Polishchuk improved the CMake testing.
  316. Ikko Ashimine fixed a typo.

Thanks a lot for helping out! Please let me know if I forgot someone.

Used third-party tools

The library itself consists of a single header file licensed under the MIT license. However, it is built, tested, documented, and whatnot using a lot of third-party tools and services. Thanks a lot!

Projects using JSON for Modern C++

The library is currently used in Apple macOS Sierra-Monterey and iOS 10-15. I am not sure what they are using the library for, but I am happy that it runs on so many devices.

Notes

Character encoding

The library supports Unicode input as follows:

  • Only UTF-8 encoded input is supported which is the default encoding for JSON according to RFC 8259.
  • std::u16string
    and can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers.
    std::u32string
  • Other encodings such as Latin-1 or ISO 8859-1 are not supported and will yield parse or serialization errors.
  • Unicode noncharacters will not be replaced by the library.
  • Invalid surrogates (e.g., incomplete pairs such as ) will yield parse errors.
    \uDEAD
  • The strings stored in the library are UTF-8 encoded. When using the default string type (), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs.
    std::string
  • When you store strings with different encodings in the library, calling
    dump()
    may throw an exception unless or are used as error handlers.
    json::error_handler_t::replace
    json::error_handler_t::ignore
  • To store wide strings (e.g., ), you need to convert them to a UTF-8 encoded before, see an example.
    std::wstring
    std::string

Comments in JSON

This library does not support comments by default. It does so for three reasons:

  1. Comments are not part of the JSON specification. You may argue that or are allowed in JavaScript, but JSON is not JavaScript.

    //
    /* */

  2. This was not an oversight: Douglas Crockford wrote on this in May 2012:

    I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't.

    Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser.

  3. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check The Harmful Consequences of the Robustness Principle on this.

However, you can pass set parameter to true in the function to ignore or comments. Comments will then be treated as whitespace.

ignore_comments
parse
//
/* */

Order of object keys

By default, the library does not preserve the insertion order of object elements. This is standards-compliant, as the JSON standard defines objects as "an unordered collection of zero or more name/value pairs".

If you do want to preserve the insertion order, you can try the type

nlohmann::ordered_json
. Alternatively, you can use a more sophisticated ordered map like
tsl::ordered_map
(integration) or
nlohmann::fifo_map
(integration).

Memory Release

We checked with Valgrind and the Address Sanitizer (ASAN) that there are no memory leaks.

If you find that a parsing program with this library does not release memory, please consider the following case, and it may be unrelated to this library.

Your program is compiled with glibc. There is a tunable threshold that glibc uses to decide whether to actually return memory to the system or whether to cache it for later reuse. If in your program you make lots of small allocations and those small allocations are not a contiguous block and are presumably below the threshold, then they will not get returned to the OS. Here is a related issue #1924.

Further notes

  • The code contains numerous debug assertions which can be switched off by defining the preprocessor macro , see the documentation of
    assert
    . In particular, note
    operator[]
    implements unchecked access for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an assertion failure if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the
    at()
    function
    . Furthermore, you can define to replace calls to .
    NDEBUG
    JSON_ASSERT(x)
    assert(x)
  • As the exact number type is not defined in the JSON specification, this library tries to choose the best fitting C++ number type automatically. As a result, the type may be used to store numbers which may yield floating-point exceptions in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions.
    double
  • The code can be compiled without C++ runtime type identification features; that is, you can use the compiler flag.
    -fno-rtti
  • 例外はライブラリ内で広く使用されています。ただし、コンパイラフラグを使用するか、シンボルを定義することでオフに切り替えることができます。この場合、例外は呼び出しに置き換えられます。この動作をさらに制御するには、(オーバーライド)、(オーバーライド)、および (オーバーライド) を定義します。現在のスコープを(スローやアボートなどによって)残し、その後も続行すると未定義の動作が発生する可能性があることに注意してください。例外が無効になっている場合、例外の説明 what() 文字列は MSVC で使用できないことに注意してください (#2824 を参照)。
    -fno-exceptions
    JSON_NOEXCEPTION
    abort()
    JSON_THROW_USER
    throw
    JSON_TRY_USER
    try
    JSON_CATCH_USER
    catch
    JSON_THROW_USER

単体テストの実行

テストをコンパイルして実行するには、

$ mkdir build
$ cd build
$ cmake .. -DJSON_BuildTests=On
$ cmake --build .
$ ctest --output-on-failure

ステージ中に、いくつかのJSONテストファイルが外部リポジトリからダウンロードされることに注意してください。ポリシーでテスト中のアーティファクトのダウンロードが禁止されている場合は、ファイルを自分でダウンロードし、テスト ファイルを含むディレクトリを CMake に渡すことができます。その後、インターネット接続は必要ありません。詳細については、問題 #2189 を参照してください。

ctest
-DJSON_TestDataDirectory=path

テスト スイートが見つからない場合、いくつかのテスト スイートは次のように失敗します。

===============================================================================
json/tests/src/make_test_data_available.hpp:21:
TEST CASE:  check test suite is downloaded

json/tests/src/make_test_data_available.hpp:23: FATAL ERROR: REQUIRE( utils::check_testsuite_downloaded() ) is NOT correct!
  values: REQUIRE( false )
  logged: Test data not found in 'json/cmake-build-debug/json_test_data'.
          Please execute target 'download_test_data' before running this test suite.
          See <https://github.com/nlohmann/json#execute-unit-tests> for more information.

===============================================================================

Git経由でコードをチェックアウトするのではなく、ライブラリをダウンロードした場合、テストは失敗します。これらのテストをスキップして実行してください。詳細については、問題 #2189 を参照してください。

cmake_fetch_content_configure
ctest -LE git_required

一部のテストでは、インストールされているファイルが変更されるため、プロセス全体を再現できなくなります。これらのテストをスキップして実行してください。詳細については、問題 #2324 を参照してください。

ctest -LE not_reproducible

両方のラベルを除外するには、呼び出す必要があることに注意してください。詳細については、問題 #2596 を参照してください。

cmake -LE "not_reproducible|git_required"

Intel コンパイラは既定で安全でない浮動小数点最適化を使用するため、単体テストが失敗する可能性があります。フラグを使用します /fp:正確です。