Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add note on derived return type for value function #4628

Merged
merged 2 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/mkdocs/docs/api/basic_json/at.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
24 changes: 24 additions & 0 deletions docs/mkdocs/docs/api/basic_json/value.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
14 changes: 14 additions & 0 deletions docs/mkdocs/docs/examples/value__return_type.cpp
Original file line number Diff line number Diff line change
@@ -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';
}
4 changes: 4 additions & 0 deletions docs/mkdocs/docs/examples/value__return_type.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
operator[]: 18446744073709551615
default value (int): -1
default value (uint64_t): 18446744073709551615
explict return value type: 18446744073709551615
49 changes: 40 additions & 9 deletions docs/mkdocs/docs/features/element_access/default_value.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
Loading