📝 add note on derived return type

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann 2025-01-25 11:38:59 +01:00
parent d0789e365d
commit 3f9d9c7cd5
No known key found for this signature in database
GPG Key ID: 7F3CEA63AE251B69
5 changed files with 84 additions and 11 deletions

View File

@ -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

View File

@ -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 return type of the `value` function is determined by the type of the provided default value. 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"

View File

@ -0,0 +1,14 @@
#include <iostream>
#include <nlohmann/json.hpp>
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<std::uint64_t>("uint64", 0) << '\n';
}

View File

@ -0,0 +1,4 @@
operator[]: 18446744073709551615
default value (int): -1
default value (uint64_t): 18446744073709551615
explict return value type: 18446744073709551615

View File

@ -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
@ -18,15 +22,42 @@ 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"` |
## 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 return type of the `value` function is determined by the type of the provided default value. 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"
```
## See also
- [`value`](../../api/basic_json/value.md) for access with default value
- documentation on [checked access](checked_access.md)