Skip to content

Commit e90c860

Browse files
authored
Add note on derived return type for value function (#4628)
* 📝 add note on derived return type Signed-off-by: Niels Lohmann <[email protected]> * 📝 add note on derived return type Signed-off-by: Niels Lohmann <[email protected]> --------- Signed-off-by: Niels Lohmann <[email protected]>
1 parent d0789e3 commit e90c860

File tree

5 files changed

+84
-11
lines changed

5 files changed

+84
-11
lines changed

docs/mkdocs/docs/api/basic_json/at.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ Strong exception safety: if an exception occurs, the original value stays intact
215215
## See also
216216
217217
- documentation on [checked access](../../features/element_access/checked_access.md)
218-
- see [`operator[]`](operator%5B%5D.md) for unchecked access by reference
219-
- see [`value`](value.md) for access with default value
218+
- [`operator[]`](operator%5B%5D.md) for unchecked access by reference
219+
- [`value`](value.md) for access with default value
220220
221221
## Version history
222222

docs/mkdocs/docs/api/basic_json/value.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,30 @@ changes to any JSON value.
103103
2. Logarithmic in the size of the container.
104104
3. Logarithmic in the size of the container.
105105
106+
## Notes
107+
108+
!!! warning "Return type"
109+
110+
The value function is a template, and the return type of the function is determined by the type of the provided
111+
default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit
112+
unsigned integer. We get exactly that value when using [`operator[]`](operator[].md). However, when we call `value`
113+
and provide `#!c 0` as default value, then `#!c -1` is returned. The occurs, because `#!c 0` has type `#!c int`
114+
which overflows when handling the value `#!c 18446744073709551615`.
115+
116+
To address this issue, either provide a correctly typed default value or use the template parameter to specify the
117+
desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default
118+
value is not used as the return value.
119+
120+
```cpp
121+
--8<-- "examples/value__return_type.cpp"
122+
```
123+
124+
Output:
125+
126+
```json
127+
--8<-- "examples/value__return_type.output"
128+
```
129+
106130
## Examples
107131
108132
??? example "Example: (1) access specified object element with default value"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <iostream>
2+
#include <nlohmann/json.hpp>
3+
4+
using json = nlohmann::json;
5+
6+
int main()
7+
{
8+
json j = json::parse(R"({"uint64": 18446744073709551615})");
9+
10+
std::cout << "operator[]: " << j["uint64"] << '\n'
11+
<< "default value (int): " << j.value("uint64", 0) << '\n'
12+
<< "default value (uint64_t): " << j.value("uint64", std::uint64_t(0)) << '\n'
13+
<< "explict return value type: " << j.value<std::uint64_t>("uint64", 0) << '\n';
14+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
operator[]: 18446744073709551615
2+
default value (int): -1
3+
default value (uint64_t): 18446744073709551615
4+
explict return value type: 18446744073709551615

docs/mkdocs/docs/features/element_access/default_value.md

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
## Overview
44

5-
In many situations such as configuration files, missing values are not exceptional, but may be treated as if a default value was present.
5+
In many situations such as configuration files, missing values are not exceptional, but may be treated as if a default
6+
value was present. For this case, use [`value(key, default_value)`](../../api/basic_json/value.md) which takes the key
7+
you want to access and a default value in case there is no value stored with that key.
8+
9+
## Example
610

711
??? example
812

@@ -17,16 +21,43 @@ In many situations such as configuration files, missing values are not exception
1721

1822
Assume the value is parsed to a `json` variable `j`.
1923

20-
| expression | value |
21-
| ---------- | ----- |
22-
| `#!cpp j` | `#!json {"logOutput": "result.log", "append": true}` |
23-
| `#!cpp j.value("logOutput", "logfile.log")` | `#!json "result.log"` |
24-
| `#!cpp j.value("append", true)` | `#!json true` |
25-
| `#!cpp j.value("append", false)` | `#!json true` |
26-
| `#!cpp j.value("logLevel", "verbose")` | `#!json "verbose"` |
24+
| expression | value |
25+
|---------------------------------------------|------------------------------------------------------|
26+
| `#!cpp j` | `#!json {"logOutput": "result.log", "append": true}` |
27+
| `#!cpp j.value("logOutput", "logfile.log")` | `#!json "result.log"` |
28+
| `#!cpp j.value("append", true)` | `#!json true` |
29+
| `#!cpp j.value("append", false)` | `#!json true` |
30+
| `#!cpp j.value("logLevel", "verbose")` | `#!json "verbose"` |
2731

28-
## Note
32+
## Notes
2933

3034
!!! failure "Exceptions"
3135

3236
- `value` can only be used with objects. For other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error306) is thrown.
37+
38+
!!! warning "Return type"
39+
40+
The value function is a template, and the return type of the function is determined by the type of the provided
41+
default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit
42+
unsigned integer. We get exactly that value when using [`operator[]`](../../api/basic_json/operator[].md). However,
43+
when we call `value` and provide `#!c 0` as default value, then `#!c -1` is returned. The occurs, because `#!c 0`
44+
has type `#!c int` which overflows when handling the value `#!c 18446744073709551615`.
45+
46+
To address this issue, either provide a correctly typed default value or use the template parameter to specify the
47+
desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default
48+
value is not used as the return value.
49+
50+
```cpp
51+
--8<-- "examples/value__return_type.cpp"
52+
```
53+
54+
Output:
55+
56+
```json
57+
--8<-- "examples/value__return_type.output"
58+
```
59+
60+
## See also
61+
62+
- [`value`](../../api/basic_json/value.md) for access with default value
63+
- documentation on [checked access](checked_access.md)

0 commit comments

Comments
 (0)