mirror of
https://github.com/nlohmann/json.git
synced 2025-12-11 14:22:35 +03:00
Use get instead of template get in REAMD.md and docs in non-template context (#4846)
Signed-off-by: Andy Choi <ccpong516@gmail.com>
This commit is contained in:
38
README.md
38
README.md
@@ -345,7 +345,7 @@ Note the difference between serialization and assignment:
|
|||||||
json j_string = "this is a string";
|
json j_string = "this is a string";
|
||||||
|
|
||||||
// retrieve the string value
|
// retrieve the string value
|
||||||
auto cpp_string = j_string.template get<std::string>();
|
auto cpp_string = j_string.get<std::string>();
|
||||||
// retrieve the string value (alternative when a variable already exists)
|
// retrieve the string value (alternative when a variable already exists)
|
||||||
std::string cpp_string2;
|
std::string cpp_string2;
|
||||||
j_string.get_to(cpp_string2);
|
j_string.get_to(cpp_string2);
|
||||||
@@ -354,7 +354,7 @@ j_string.get_to(cpp_string2);
|
|||||||
std::string serialized_string = j_string.dump();
|
std::string serialized_string = j_string.dump();
|
||||||
|
|
||||||
// output of original string
|
// output of original string
|
||||||
std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.template get<std::string>() << '\n';
|
std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::string>() << '\n';
|
||||||
// output of serialized value
|
// output of serialized value
|
||||||
std::cout << j_string << " == " << serialized_string << std::endl;
|
std::cout << j_string << " == " << serialized_string << std::endl;
|
||||||
```
|
```
|
||||||
@@ -527,7 +527,7 @@ for (auto& element : j) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getter/setter
|
// getter/setter
|
||||||
const auto tmp = j[0].template get<std::string>();
|
const auto tmp = j[0].get<std::string>();
|
||||||
j[1] = 42;
|
j[1] = 42;
|
||||||
bool foo = j.at(2);
|
bool foo = j.at(2);
|
||||||
|
|
||||||
@@ -734,7 +734,7 @@ You can switch off implicit conversions by defining `JSON_USE_IMPLICIT_CONVERSIO
|
|||||||
// strings
|
// strings
|
||||||
std::string s1 = "Hello, world!";
|
std::string s1 = "Hello, world!";
|
||||||
json js = s1;
|
json js = s1;
|
||||||
auto s2 = js.template get<std::string>();
|
auto s2 = js.get<std::string>();
|
||||||
// NOT RECOMMENDED
|
// NOT RECOMMENDED
|
||||||
std::string s3 = js;
|
std::string s3 = js;
|
||||||
std::string s4;
|
std::string s4;
|
||||||
@@ -743,7 +743,7 @@ s4 = js;
|
|||||||
// Booleans
|
// Booleans
|
||||||
bool b1 = true;
|
bool b1 = true;
|
||||||
json jb = b1;
|
json jb = b1;
|
||||||
auto b2 = jb.template get<bool>();
|
auto b2 = jb.get<bool>();
|
||||||
// NOT RECOMMENDED
|
// NOT RECOMMENDED
|
||||||
bool b3 = jb;
|
bool b3 = jb;
|
||||||
bool b4;
|
bool b4;
|
||||||
@@ -752,7 +752,7 @@ b4 = jb;
|
|||||||
// numbers
|
// numbers
|
||||||
int i = 42;
|
int i = 42;
|
||||||
json jn = i;
|
json jn = i;
|
||||||
auto f = jn.template get<double>();
|
auto f = jn.get<double>();
|
||||||
// NOT RECOMMENDED
|
// NOT RECOMMENDED
|
||||||
double f2 = jb;
|
double f2 = jb;
|
||||||
double f3;
|
double f3;
|
||||||
@@ -795,9 +795,9 @@ j["age"] = p.age;
|
|||||||
|
|
||||||
// convert from JSON: copy each value from the JSON object
|
// convert from JSON: copy each value from the JSON object
|
||||||
ns::person p {
|
ns::person p {
|
||||||
j["name"].template get<std::string>(),
|
j["name"].get<std::string>(),
|
||||||
j["address"].template get<std::string>(),
|
j["address"].get<std::string>(),
|
||||||
j["age"].template get<int>()
|
j["age"].get<int>()
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -814,7 +814,7 @@ std::cout << j << std::endl;
|
|||||||
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
|
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
|
||||||
|
|
||||||
// conversion: json -> person
|
// conversion: json -> person
|
||||||
auto p2 = j.template get<ns::person>();
|
auto p2 = j.get<ns::person>();
|
||||||
|
|
||||||
// that's it
|
// that's it
|
||||||
assert(p == p2);
|
assert(p == p2);
|
||||||
@@ -841,13 +841,13 @@ namespace ns {
|
|||||||
```
|
```
|
||||||
|
|
||||||
That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.
|
That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.
|
||||||
Likewise, when calling `template get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.
|
Likewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.
|
||||||
|
|
||||||
Some important things:
|
Some important things:
|
||||||
|
|
||||||
- Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
|
- Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
|
||||||
- Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
|
- Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
|
||||||
- When using `template get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
|
- When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
|
||||||
- In function `from_json`, use function [`at()`](https://json.nlohmann.me/api/basic_json/at/) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
|
- In function `from_json`, use function [`at()`](https://json.nlohmann.me/api/basic_json/at/) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
|
||||||
- You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.
|
- You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.
|
||||||
|
|
||||||
@@ -927,8 +927,8 @@ namespace nlohmann {
|
|||||||
if (j.is_null()) {
|
if (j.is_null()) {
|
||||||
opt = boost::none;
|
opt = boost::none;
|
||||||
} else {
|
} else {
|
||||||
opt = j.template get<T>(); // same as above, but with
|
opt = j.get<T>(); // same as above, but with
|
||||||
// adl_serializer<T>::from_json
|
// adl_serializer<T>::from_json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -955,7 +955,7 @@ namespace nlohmann {
|
|||||||
// note: the return type is no longer 'void', and the method only takes
|
// note: the return type is no longer 'void', and the method only takes
|
||||||
// one argument
|
// one argument
|
||||||
static move_only_type from_json(const json& j) {
|
static move_only_type from_json(const json& j) {
|
||||||
return {j.template get<int>()};
|
return {j.get<int>()};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here's the catch! You must provide a to_json method! Otherwise, you
|
// Here's the catch! You must provide a to_json method! Otherwise, you
|
||||||
@@ -1019,7 +1019,7 @@ struct bad_serializer
|
|||||||
static void to_json(const BasicJsonType& j, T& value) {
|
static void to_json(const BasicJsonType& j, T& value) {
|
||||||
// this calls BasicJsonType::json_serializer<T>::from_json(j, value)
|
// this calls BasicJsonType::json_serializer<T>::from_json(j, value)
|
||||||
// if BasicJsonType::json_serializer == bad_serializer ... oops!
|
// if BasicJsonType::json_serializer == bad_serializer ... oops!
|
||||||
value = j.template get<T>(); // oops!
|
value = j.get<T>(); // oops!
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
@@ -1059,11 +1059,11 @@ assert(j == "stopped");
|
|||||||
|
|
||||||
// json string to enum
|
// json string to enum
|
||||||
json j3 = "running";
|
json j3 = "running";
|
||||||
assert(j3.template get<TaskState>() == TS_RUNNING);
|
assert(j3.get<TaskState>() == TS_RUNNING);
|
||||||
|
|
||||||
// undefined json value to enum (where the first map entry above is the default)
|
// undefined json value to enum (where the first map entry above is the default)
|
||||||
json jPi = 3.14;
|
json jPi = 3.14;
|
||||||
assert(jPi.template get<TaskState>() == TS_INVALID);
|
assert(jPi.get<TaskState>() == TS_INVALID);
|
||||||
```
|
```
|
||||||
|
|
||||||
Just as in [Arbitrary Type Conversions](#arbitrary-types-conversions) above,
|
Just as in [Arbitrary Type Conversions](#arbitrary-types-conversions) above,
|
||||||
@@ -1073,7 +1073,7 @@ Just as in [Arbitrary Type Conversions](#arbitrary-types-conversions) above,
|
|||||||
|
|
||||||
Other Important points:
|
Other Important points:
|
||||||
|
|
||||||
- When using `template get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully.
|
- When using `get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully.
|
||||||
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
|
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
|
||||||
|
|
||||||
### Binary formats (BSON, CBOR, MessagePack, UBJSON, and BJData)
|
### Binary formats (BSON, CBOR, MessagePack, UBJSON, and BJData)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ Copy of the JSON value, converted to `ValueType`
|
|||||||
??? example "Example: (1) Default-constructible type"
|
??? example "Example: (1) Default-constructible type"
|
||||||
|
|
||||||
The example below shows how a `from_json` function can be implemented for a user-defined type. This function is
|
The example below shows how a `from_json` function can be implemented for a user-defined type. This function is
|
||||||
called by the `adl_serializer` when `template get<ns::person>()` is called.
|
called by the `adl_serializer` when `get<ns::person>()` is called.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
--8<-- "examples/from_json__default_constructible.cpp"
|
--8<-- "examples/from_json__default_constructible.cpp"
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ The default value is `0`.
|
|||||||
const json j = Choice::first;
|
const json j = Choice::first;
|
||||||
|
|
||||||
// normally invokes from_json parse function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not
|
// normally invokes from_json parse function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not
|
||||||
Choice ch = j.template get<Choice>();
|
Choice ch = j.get<Choice>();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ The default value is `0`.
|
|||||||
const json j = Choice::first;
|
const json j = Choice::first;
|
||||||
|
|
||||||
// uses user-defined from_json function defined by macro
|
// uses user-defined from_json function defined by macro
|
||||||
Choice ch = j.template get<Choice>();
|
Choice ch = j.get<Choice>();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ The default value is `0`.
|
|||||||
|
|
||||||
void from_json(const json& j, Choice& ch)
|
void from_json(const json& j, Choice& ch)
|
||||||
{
|
{
|
||||||
auto value = j.template get<std::string>();
|
auto value = j.get<std::string>();
|
||||||
if (value == "first")
|
if (value == "first")
|
||||||
{
|
{
|
||||||
ch = Choice::first;
|
ch = Choice::first;
|
||||||
@@ -122,7 +122,7 @@ The default value is `0`.
|
|||||||
|
|
||||||
void to_json(json& j, const Choice& ch)
|
void to_json(json& j, const Choice& ch)
|
||||||
{
|
{
|
||||||
auto value = j.template get<std::string>();
|
auto value = j.get<std::string>();
|
||||||
if (value == "first")
|
if (value == "first")
|
||||||
{
|
{
|
||||||
ch = Choice::first;
|
ch = Choice::first;
|
||||||
@@ -139,7 +139,7 @@ The default value is `0`.
|
|||||||
const json j = Choice::first;
|
const json j = Choice::first;
|
||||||
|
|
||||||
// uses user-defined from_json function
|
// uses user-defined from_json function
|
||||||
Choice ch = j.template get<Choice>();
|
Choice ch = j.get<Choice>();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ By default, implicit conversions are enabled.
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
json j = "Hello, world!";
|
json j = "Hello, world!";
|
||||||
auto s = j.template get<std::string>();
|
auto s = j.get<std::string>();
|
||||||
```
|
```
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ inline void from_json(const BasicJsonType& j, type& e);
|
|||||||
|
|
||||||
!!! important "Important notes"
|
!!! important "Important notes"
|
||||||
|
|
||||||
- When using [`template get<ENUM_TYPE>()`](../basic_json/get.md), undefined JSON values will default to the first specified
|
- When using [`get<ENUM_TYPE>()`](../basic_json/get.md), undefined JSON values will default to the first specified
|
||||||
conversion. Select this default pair carefully. See example 1 below.
|
conversion. Select this default pair carefully. See example 1 below.
|
||||||
- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the
|
- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the
|
||||||
list will be returned when converting to or from JSON. See example 2 below.
|
list will be returned when converting to or from JSON. See example 2 below.
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ int main()
|
|||||||
j["address"] = "744 Evergreen Terrace";
|
j["address"] = "744 Evergreen Terrace";
|
||||||
j["age"] = 60;
|
j["age"] = 60;
|
||||||
|
|
||||||
auto p = j.template get<ns::person>();
|
auto p = j.get<ns::person>();
|
||||||
|
|
||||||
std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl;
|
std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ int main()
|
|||||||
j["address"] = "744 Evergreen Terrace";
|
j["address"] = "744 Evergreen Terrace";
|
||||||
j["age"] = 60;
|
j["age"] = 60;
|
||||||
|
|
||||||
auto p = j.template get<ns::person>();
|
auto p = j.get<ns::person>();
|
||||||
|
|
||||||
std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl;
|
std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ int main()
|
|||||||
json value = 17;
|
json value = 17;
|
||||||
|
|
||||||
// explicitly getting pointers
|
// explicitly getting pointers
|
||||||
auto p1 = value.template get<const json::number_integer_t*>();
|
auto p1 = value.get<const json::number_integer_t*>();
|
||||||
auto p2 = value.template get<json::number_integer_t*>();
|
auto p2 = value.get<json::number_integer_t*>();
|
||||||
auto p3 = value.template get<json::number_integer_t* const>();
|
auto p3 = value.get<json::number_integer_t* const>();
|
||||||
auto p4 = value.template get<const json::number_integer_t* const>();
|
auto p4 = value.get<const json::number_integer_t* const>();
|
||||||
auto p5 = value.template get<json::number_float_t*>();
|
auto p5 = value.get<json::number_float_t*>();
|
||||||
|
|
||||||
// print the pointees
|
// print the pointees
|
||||||
std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\n';
|
std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\n';
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ int main()
|
|||||||
};
|
};
|
||||||
|
|
||||||
// use explicit conversions
|
// use explicit conversions
|
||||||
auto v1 = json_types["boolean"].template get<bool>();
|
auto v1 = json_types["boolean"].get<bool>();
|
||||||
auto v2 = json_types["number"]["integer"].template get<int>();
|
auto v2 = json_types["number"]["integer"].get<int>();
|
||||||
auto v3 = json_types["number"]["integer"].template get<short>();
|
auto v3 = json_types["number"]["integer"].get<short>();
|
||||||
auto v4 = json_types["number"]["floating-point"].template get<float>();
|
auto v4 = json_types["number"]["floating-point"].get<float>();
|
||||||
auto v5 = json_types["number"]["floating-point"].template get<int>();
|
auto v5 = json_types["number"]["floating-point"].get<int>();
|
||||||
auto v6 = json_types["string"].template get<std::string>();
|
auto v6 = json_types["string"].get<std::string>();
|
||||||
auto v7 = json_types["array"].template get<std::vector<short>>();
|
auto v7 = json_types["array"].get<std::vector<short>>();
|
||||||
auto v8 = json_types.template get<std::unordered_map<std::string, json>>();
|
auto v8 = json_types.get<std::unordered_map<std::string, json>>();
|
||||||
|
|
||||||
// print the conversion results
|
// print the conversion results
|
||||||
std::cout << v1 << '\n';
|
std::cout << v1 << '\n';
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ int main()
|
|||||||
|
|
||||||
// deserialization: json -> person
|
// deserialization: json -> person
|
||||||
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
||||||
auto p2 = j2.template get<ns::person>();
|
auto p2 = j2.get<ns::person>();
|
||||||
|
|
||||||
// incomplete deserialization:
|
// incomplete deserialization:
|
||||||
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto p3 = j3.template get<ns::person>();
|
auto p3 = j3.get<ns::person>();
|
||||||
}
|
}
|
||||||
catch (const json::exception& e)
|
catch (const json::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ int main()
|
|||||||
|
|
||||||
// deserialization: json -> person
|
// deserialization: json -> person
|
||||||
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
||||||
auto p2 = j2.template get<ns::person>();
|
auto p2 = j2.get<ns::person>();
|
||||||
|
|
||||||
// incomplete deserialization:
|
// incomplete deserialization:
|
||||||
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto p3 = j3.template get<ns::person>();
|
auto p3 = j3.get<ns::person>();
|
||||||
}
|
}
|
||||||
catch (const json::exception& e)
|
catch (const json::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ int main()
|
|||||||
|
|
||||||
// deserialization: json -> person
|
// deserialization: json -> person
|
||||||
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
||||||
auto p2 = j2.template get<ns::person>();
|
auto p2 = j2.get<ns::person>();
|
||||||
|
|
||||||
// incomplete deserialization:
|
// incomplete deserialization:
|
||||||
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
||||||
auto p3 = j3.template get<ns::person>();
|
auto p3 = j3.get<ns::person>();
|
||||||
std::cout << "roundtrip: " << json(p3) << std::endl;
|
std::cout << "roundtrip: " << json(p3) << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ int main()
|
|||||||
|
|
||||||
// deserialization: json -> person
|
// deserialization: json -> person
|
||||||
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
||||||
auto p2 = j2.template get<ns::person>();
|
auto p2 = j2.get<ns::person>();
|
||||||
|
|
||||||
// incomplete deserialization:
|
// incomplete deserialization:
|
||||||
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
||||||
auto p3 = j3.template get<ns::person>();
|
auto p3 = j3.get<ns::person>();
|
||||||
std::cout << "roundtrip: " << json(p3) << std::endl;
|
std::cout << "roundtrip: " << json(p3) << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ int main()
|
|||||||
|
|
||||||
// deserialization: json -> person
|
// deserialization: json -> person
|
||||||
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
||||||
auto p2 = j2.template get<ns::person>();
|
auto p2 = j2.get<ns::person>();
|
||||||
|
|
||||||
// incomplete deserialization:
|
// incomplete deserialization:
|
||||||
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto p3 = j3.template get<ns::person>();
|
auto p3 = j3.get<ns::person>();
|
||||||
}
|
}
|
||||||
catch (const json::exception& e)
|
catch (const json::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ int main()
|
|||||||
|
|
||||||
// deserialization: json -> person
|
// deserialization: json -> person
|
||||||
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
||||||
auto p2 = j2.template get<ns::person>();
|
auto p2 = j2.get<ns::person>();
|
||||||
|
|
||||||
// incomplete deserialization:
|
// incomplete deserialization:
|
||||||
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto p3 = j3.template get<ns::person>();
|
auto p3 = j3.get<ns::person>();
|
||||||
}
|
}
|
||||||
catch (const json::exception& e)
|
catch (const json::exception& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ int main()
|
|||||||
|
|
||||||
// deserialization: json -> person
|
// deserialization: json -> person
|
||||||
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
||||||
auto p2 = j2.template get<ns::person>();
|
auto p2 = j2.get<ns::person>();
|
||||||
|
|
||||||
// incomplete deserialization:
|
// incomplete deserialization:
|
||||||
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
||||||
auto p3 = j3.template get<ns::person>();
|
auto p3 = j3.get<ns::person>();
|
||||||
std::cout << "roundtrip: " << json(p3) << std::endl;
|
std::cout << "roundtrip: " << json(p3) << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ int main()
|
|||||||
|
|
||||||
// deserialization: json -> person
|
// deserialization: json -> person
|
||||||
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json;
|
||||||
auto p2 = j2.template get<ns::person>();
|
auto p2 = j2.get<ns::person>();
|
||||||
|
|
||||||
// incomplete deserialization:
|
// incomplete deserialization:
|
||||||
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
|
||||||
auto p3 = j3.template get<ns::person>();
|
auto p3 = j3.get<ns::person>();
|
||||||
std::cout << "roundtrip: " << json(p3) << std::endl;
|
std::cout << "roundtrip: " << json(p3) << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,16 +44,16 @@ int main()
|
|||||||
// deserialization
|
// deserialization
|
||||||
json j_running = "running";
|
json j_running = "running";
|
||||||
json j_blue = "blue";
|
json j_blue = "blue";
|
||||||
auto running = j_running.template get<ns::TaskState>();
|
auto running = j_running.get<ns::TaskState>();
|
||||||
auto blue = j_blue.template get<ns::Color>();
|
auto blue = j_blue.get<ns::Color>();
|
||||||
std::cout << j_running << " -> " << running
|
std::cout << j_running << " -> " << running
|
||||||
<< ", " << j_blue << " -> " << static_cast<int>(blue) << std::endl;
|
<< ", " << j_blue << " -> " << static_cast<int>(blue) << std::endl;
|
||||||
|
|
||||||
// deserializing undefined JSON value to enum
|
// deserializing undefined JSON value to enum
|
||||||
// (where the first map entry above is the default)
|
// (where the first map entry above is the default)
|
||||||
json j_pi = 3.14;
|
json j_pi = 3.14;
|
||||||
auto invalid = j_pi.template get<ns::TaskState>();
|
auto invalid = j_pi.get<ns::TaskState>();
|
||||||
auto unknown = j_pi.template get<ns::Color>();
|
auto unknown = j_pi.get<ns::Color>();
|
||||||
std::cout << j_pi << " -> " << invalid << ", "
|
std::cout << j_pi << " -> " << invalid << ", "
|
||||||
<< j_pi << " -> " << static_cast<int>(unknown) << std::endl;
|
<< j_pi << " -> " << static_cast<int>(unknown) << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ int main()
|
|||||||
|
|
||||||
// deserialization
|
// deserialization
|
||||||
json j_rot = "rot";
|
json j_rot = "rot";
|
||||||
auto rot = j_rot.template get<ns::Color>();
|
auto rot = j_rot.get<ns::Color>();
|
||||||
auto red = j_red.template get<ns::Color>();
|
auto red = j_red.get<ns::Color>();
|
||||||
std::cout << j_rot << " -> " << static_cast<int>(rot) << std::endl;
|
std::cout << j_rot << " -> " << static_cast<int>(rot) << std::endl;
|
||||||
std::cout << j_red << " -> " << static_cast<int>(red) << std::endl;
|
std::cout << j_red << " -> " << static_cast<int>(red) << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ j["age"] = p.age;
|
|||||||
|
|
||||||
// convert from JSON: copy each value from the JSON object
|
// convert from JSON: copy each value from the JSON object
|
||||||
ns::person p {
|
ns::person p {
|
||||||
j["name"].template get<std::string>(),
|
j["name"].get<std::string>(),
|
||||||
j["address"].template get<std::string>(),
|
j["address"].get<std::string>(),
|
||||||
j["age"].template get<int>()
|
j["age"].get<int>()
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ std::cout << j << std::endl;
|
|||||||
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
|
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
|
||||||
|
|
||||||
// conversion: json -> person
|
// conversion: json -> person
|
||||||
auto p2 = j.template get<ns::person>();
|
auto p2 = j.get<ns::person>();
|
||||||
|
|
||||||
// that's it
|
// that's it
|
||||||
assert(p == p2);
|
assert(p == p2);
|
||||||
@@ -70,13 +70,13 @@ namespace ns {
|
|||||||
```
|
```
|
||||||
|
|
||||||
That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.
|
That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.
|
||||||
Likewise, when calling `template get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.
|
Likewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.
|
||||||
|
|
||||||
Some important things:
|
Some important things:
|
||||||
|
|
||||||
* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
|
* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
|
||||||
* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [#1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
|
* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [#1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
|
||||||
* When using `template get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
|
* When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
|
||||||
* In function `from_json`, use function [`at()`](../api/basic_json/at.md) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
|
* In function `from_json`, use function [`at()`](../api/basic_json/at.md) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
|
||||||
* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.
|
* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ struct adl_serializer<boost::optional<T>> {
|
|||||||
if (j.is_null()) {
|
if (j.is_null()) {
|
||||||
opt = boost::none;
|
opt = boost::none;
|
||||||
} else {
|
} else {
|
||||||
opt = j.template get<T>(); // same as above, but with
|
opt = j.get<T>(); // same as above, but with
|
||||||
// adl_serializer<T>::from_json
|
// adl_serializer<T>::from_json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,7 +224,7 @@ namespace nlohmann {
|
|||||||
// note: the return type is no longer 'void', and the method only takes
|
// note: the return type is no longer 'void', and the method only takes
|
||||||
// one argument
|
// one argument
|
||||||
static move_only_type from_json(const json& j) {
|
static move_only_type from_json(const json& j) {
|
||||||
return {j.template get<int>()};
|
return {j.get<int>()};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here's the catch! You must provide a to_json method! Otherwise, you
|
// Here's the catch! You must provide a to_json method! Otherwise, you
|
||||||
@@ -288,7 +288,7 @@ struct bad_serializer
|
|||||||
static void from_json(const BasicJsonType& j, T& value) {
|
static void from_json(const BasicJsonType& j, T& value) {
|
||||||
// this calls BasicJsonType::json_serializer<T>::from_json(j, value);
|
// this calls BasicJsonType::json_serializer<T>::from_json(j, value);
|
||||||
// if BasicJsonType::json_serializer == bad_serializer ... oops!
|
// if BasicJsonType::json_serializer == bad_serializer ... oops!
|
||||||
value = j.template template get<T>(); // oops!
|
value = j.template get<T>(); // oops!
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -36,11 +36,11 @@ assert(j == "stopped");
|
|||||||
|
|
||||||
// json string to enum
|
// json string to enum
|
||||||
json j3 = "running";
|
json j3 = "running";
|
||||||
assert(j3.template get<TaskState>() == TS_RUNNING);
|
assert(j3.get<TaskState>() == TS_RUNNING);
|
||||||
|
|
||||||
// undefined json value to enum (where the first map entry above is the default)
|
// undefined json value to enum (where the first map entry above is the default)
|
||||||
json jPi = 3.14;
|
json jPi = 3.14;
|
||||||
assert(jPi.template get<TaskState>() == TS_INVALID );
|
assert(jPi.get<TaskState>() == TS_INVALID );
|
||||||
```
|
```
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
@@ -54,7 +54,7 @@ Just as in [Arbitrary Type Conversions](arbitrary_types.md) above,
|
|||||||
|
|
||||||
Other Important points:
|
Other Important points:
|
||||||
|
|
||||||
- When using `template get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this
|
- When using `get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this
|
||||||
default pair carefully.
|
default pair carefully.
|
||||||
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the
|
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the
|
||||||
map will be returned when converting to or from JSON.
|
map will be returned when converting to or from JSON.
|
||||||
|
|||||||
@@ -235,9 +235,9 @@ integers, and between integers and floating-point values to integers. This behav
|
|||||||
!!! warning "Unconditional number conversions"
|
!!! warning "Unconditional number conversions"
|
||||||
|
|
||||||
```cpp hl_lines="3"
|
```cpp hl_lines="3"
|
||||||
double d = 42.3; // non-integer double value 42.3
|
double d = 42.3; // non-integer double value 42.3
|
||||||
json jd = d; // stores double value 42.3
|
json jd = d; // stores double value 42.3
|
||||||
std::int64_t i = jd.template get<std::int64_t>(); // now i==42; no warning or error is produced
|
std::int64_t i = jd.get<std::int64_t>(); // now i==42; no warning or error is produced
|
||||||
```
|
```
|
||||||
|
|
||||||
Note the last line with throw a [`json.exception.type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302)
|
Note the last line with throw a [`json.exception.type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302)
|
||||||
@@ -259,7 +259,7 @@ The rationale is twofold:
|
|||||||
if (jd.is_number_integer())
|
if (jd.is_number_integer())
|
||||||
{
|
{
|
||||||
// if so, do the conversion and use i
|
// if so, do the conversion and use i
|
||||||
std::int64_t i = jd.template get<std::int64_t>();
|
std::int64_t i = jd.get<std::int64_t>();
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ conversions with calls to [`get`](../api/basic_json/get.md), [`get_to`](../api/b
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
nlohmann::json j = "Hello, world!";
|
nlohmann::json j = "Hello, world!";
|
||||||
auto s = j.template get<std::string>();
|
auto s = j.get<std::string>();
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Future-proof (alternative)"
|
=== "Future-proof (alternative)"
|
||||||
|
|||||||
Reference in New Issue
Block a user