diff --git a/docs/mkdocs/docs/api/basic_json/at.md b/docs/mkdocs/docs/api/basic_json/at.md index 5e9504508..641f0d736 100644 --- a/docs/mkdocs/docs/api/basic_json/at.md +++ b/docs/mkdocs/docs/api/basic_json/at.md @@ -215,8 +215,8 @@ Strong exception safety: if an exception occurs, the original value stays intact ## See also - documentation on [checked access](../../features/element_access/checked_access.md) -- see [`operator[]`](operator%5B%5D.md) for unchecked access by reference -- see [`value`](value.md) for access with default value +- [`operator[]`](operator%5B%5D.md) for unchecked access by reference +- [`value`](value.md) for access with default value ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/value.md b/docs/mkdocs/docs/api/basic_json/value.md index edb5406ba..c9bca6be7 100644 --- a/docs/mkdocs/docs/api/basic_json/value.md +++ b/docs/mkdocs/docs/api/basic_json/value.md @@ -103,6 +103,30 @@ changes to any JSON value. 2. Logarithmic in the size of the container. 3. Logarithmic in the size of the container. +## Notes + +!!! warning "Return type" + + The value function is a template, and the return type of the function is determined by the type of the provided + default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit + unsigned integer. We get exactly that value when using [`operator[]`](operator[].md). However, when we call `value` + and provide `#!c 0` as default value, then `#!c -1` is returned. The occurs, because `#!c 0` has type `#!c int` + which overflows when handling the value `#!c 18446744073709551615`. + + To address this issue, either provide a correctly typed default value or use the template parameter to specify the + desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default + value is not used as the return value. + + ```cpp + --8<-- "examples/value__return_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/value__return_type.output" + ``` + ## Examples ??? example "Example: (1) access specified object element with default value" diff --git a/docs/mkdocs/docs/examples/value__return_type.cpp b/docs/mkdocs/docs/examples/value__return_type.cpp new file mode 100644 index 000000000..51ab7afa0 --- /dev/null +++ b/docs/mkdocs/docs/examples/value__return_type.cpp @@ -0,0 +1,14 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + json j = json::parse(R"({"uint64": 18446744073709551615})"); + + std::cout << "operator[]: " << j["uint64"] << '\n' + << "default value (int): " << j.value("uint64", 0) << '\n' + << "default value (uint64_t): " << j.value("uint64", std::uint64_t(0)) << '\n' + << "explict return value type: " << j.value("uint64", 0) << '\n'; +} diff --git a/docs/mkdocs/docs/examples/value__return_type.output b/docs/mkdocs/docs/examples/value__return_type.output new file mode 100644 index 000000000..9d43f5e6e --- /dev/null +++ b/docs/mkdocs/docs/examples/value__return_type.output @@ -0,0 +1,4 @@ +operator[]: 18446744073709551615 +default value (int): -1 +default value (uint64_t): 18446744073709551615 +explict return value type: 18446744073709551615 diff --git a/docs/mkdocs/docs/features/element_access/default_value.md b/docs/mkdocs/docs/features/element_access/default_value.md index 02b4fea3f..d169da518 100644 --- a/docs/mkdocs/docs/features/element_access/default_value.md +++ b/docs/mkdocs/docs/features/element_access/default_value.md @@ -2,7 +2,11 @@ ## Overview -In many situations such as configuration files, missing values are not exceptional, but may be treated as if a default value was present. +In many situations such as configuration files, missing values are not exceptional, but may be treated as if a default +value was present. For this case, use [`value(key, default_value)`](../../api/basic_json/value.md) which takes the key +you want to access and a default value in case there is no value stored with that key. + +## Example ??? example @@ -17,16 +21,43 @@ In many situations such as configuration files, missing values are not exception Assume the value is parsed to a `json` variable `j`. - | expression | value | - | ---------- | ----- | - | `#!cpp j` | `#!json {"logOutput": "result.log", "append": true}` | - | `#!cpp j.value("logOutput", "logfile.log")` | `#!json "result.log"` | - | `#!cpp j.value("append", true)` | `#!json true` | - | `#!cpp j.value("append", false)` | `#!json true` | - | `#!cpp j.value("logLevel", "verbose")` | `#!json "verbose"` | + | expression | value | + |---------------------------------------------|------------------------------------------------------| + | `#!cpp j` | `#!json {"logOutput": "result.log", "append": true}` | + | `#!cpp j.value("logOutput", "logfile.log")` | `#!json "result.log"` | + | `#!cpp j.value("append", true)` | `#!json true` | + | `#!cpp j.value("append", false)` | `#!json true` | + | `#!cpp j.value("logLevel", "verbose")` | `#!json "verbose"` | -## Note +## Notes !!! failure "Exceptions" - `value` can only be used with objects. For other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error306) is thrown. + +!!! warning "Return type" + + The value function is a template, and the return type of the function is determined by the type of the provided + default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit + unsigned integer. We get exactly that value when using [`operator[]`](../../api/basic_json/operator[].md). However, + when we call `value` and provide `#!c 0` as default value, then `#!c -1` is returned. The occurs, because `#!c 0` + has type `#!c int` which overflows when handling the value `#!c 18446744073709551615`. + + To address this issue, either provide a correctly typed default value or use the template parameter to specify the + desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default + value is not used as the return value. + + ```cpp + --8<-- "examples/value__return_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/value__return_type.output" + ``` + +## See also + +- [`value`](../../api/basic_json/value.md) for access with default value +- documentation on [checked access](checked_access.md)