mirror of
https://github.com/nlohmann/json.git
synced 2026-07-12 05:25:09 +00:00
Fix documentation gaps found in a full GitHub Discussions review (#5264)
* 📡 Fix documentation gaps found in a full GitHub Discussions review Reviewed all 1008 GitHub Discussions (2020-2026) for recurring questions that better or more visible documentation would have avoided. Adds/expands documentation for ~26 distinct gaps, including: - New "Debugging" page collecting natvis, GDB pretty printer, LLDB status, and JSON_DIAGNOSTICS pointers (previously scattered/undiscoverable) - Thread-safety and schema-validation FAQ entries - StringType's char-based requirement (no wstring/u16string/u32string) - Brace-initialization-yields-arrays warning directly on the constructor reference page (previously only in the FAQ, missed by users reading the constructor docs) - std::any exclusion from get<T>(), with a manual-dispatch example - Non-string-keyed std::map serializing as an array of pairs - ordered_json compatibility with NLOHMANN_DEFINE_TYPE_* macros (already worked, was undocumented) - std::array truncation on size-mismatched conversion (no exception) - static_cast vs. get<std::optional<T>>() divergence - Recipe for omitting a std::optional field instead of emitting null - No built-in nesting-depth limit during parsing + a callback-based workaround recipe - Recipe for streaming a large homogeneous array via parser callbacks - operator>> stream-position semantics for concatenated JSON values - JSON Pointer array-vs-object creation rule for non-existing paths - CMake target name (nlohmann_json_modules) needed to link C++20 modules - ESP-IDF/PlatformIO: no official package, link to a community fork - get(key, default) as the Python dict.get() equivalent - reserve() recipe for pre-allocating array capacity - JSONC as an alias for the existing ignore_comments/ignore_trailing_commas combination (distinct from the unsupported JSON5) - items() dereferenced-element type: decltype() idiom + detail-namespace stability caveat - Various macro/type-conversion limitations (MSGPACK_DEFINE_ARRAY equivalent, char-array round-tripping, ADL serializer macro gap) Signed-off-by: Niels Lohmann <mail@nlohmann.me> * 🚶 fix format Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -84,6 +84,49 @@ which forces the explicit `get` form and can catch unintended conversions at com
|
||||
j_null.get_to(opt); // ✅ std::nullopt
|
||||
```
|
||||
|
||||
!!! warning "`static_cast` and `get<std::optional<T>>()` are not guaranteed equivalent"
|
||||
|
||||
`operator ValueType()` (used by `static_cast` and implicit conversions) intentionally excludes
|
||||
`std::optional<T>` from delegating to `get<T>()`, to avoid a constructor ambiguity with
|
||||
`std::optional<T>`'s own converting constructor from `basic_json`. As a result,
|
||||
`static_cast<std::optional<T>>(json_value)` goes through `std::optional<T>`'s own converting
|
||||
constructor rather than through `get<std::optional<T>>()`, which can behave differently -- for example,
|
||||
with a custom `adl_serializer<std::optional<T>>` specialization. Prefer `get<std::optional<T>>()`/`get_to()`
|
||||
over `static_cast` for optional types.
|
||||
|
||||
!!! warning "Converting to a fixed-size `std::array` does not check length"
|
||||
|
||||
Converting a JSON array to `#!cpp std::array<T, N>` does not check that the JSON array's size matches `N`:
|
||||
if the JSON array is longer, the extra elements are silently dropped; if it is shorter, the remaining
|
||||
`std::array` elements are left default-constructed. No exception is thrown in either case.
|
||||
|
||||
```cpp
|
||||
json j = {1, 2, 3, 4, 5};
|
||||
auto a = j.get<std::array<int, 3>>(); // {1, 2, 3} -- elements 4 and 5 silently dropped
|
||||
```
|
||||
|
||||
## Omitting a field when serializing `std::optional`
|
||||
|
||||
By default, `to_json` for `std::optional<T>` writes either the value or `#!json null` -- there is no built-in way
|
||||
to make a field disappear from the serialized object entirely when the `std::optional` is `std::nullopt`. Because
|
||||
a specialization of `adl_serializer<std::optional<T>>` only controls how the *value* is converted (it cannot
|
||||
prevent the containing object's `to_json` from inserting the key in the first place), omission has to be
|
||||
implemented in the *containing* type's `to_json`:
|
||||
|
||||
```cpp
|
||||
struct person {
|
||||
std::string name;
|
||||
std::optional<int> age;
|
||||
};
|
||||
|
||||
void to_json(json& j, const person& p) {
|
||||
j = json{{"name", p.name}};
|
||||
if (p.age) {
|
||||
j["age"] = *p.age; // key is only inserted when the optional has a value
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Putting values in
|
||||
|
||||
The reverse direction works the same way: assigning or constructing a `json` from a C++ value converts it to JSON.
|
||||
|
||||
Reference in New Issue
Block a user