mirror of
https://github.com/nlohmann/json.git
synced 2026-10-25 07:18:55 +00:00
Add pages on class-hierarchy/smart-pointer/variant/chrono recipes, working without exceptions, and large, streamed and partial input. Extend the FAQ (23 entries, Known bugs first), parse error documentation (empty-input checklist, line/column, diagnostic positions), element access, conversions, creating values, ADL troubleshooting, memory, and build/distribution notes. Add 14 examples with generated output. Correct the statement that parse errors cannot be recovered from with -fno-exceptions. The topics come from recurring questions on Stack Overflow, Reddit, Hacker News, YouTube, and the project's GitHub discussions and issues. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2.4 KiB
2.4 KiB
Element Access
There are many ways elements in a JSON value can be accessed:
- unchecked access via
operator[] - checked access via
at - access with default value via
value - iterators
- JSON pointers
Testing whether a key or index exists before accessing it is also possible, with
contains or find (which returns an iterator to
the value, or end() if it is not found).
flowchart TD
A["accessing a value"] --> B{"must it exist?"}
B -->|"yes, missing is an error"| C["at() -- throws"]
B -->|"yes, but checking is my job"| D["operator[] -- unchecked"]
B -->|"no, a fallback is fine"| E["value() -- default value"]
A --> F{"just testing first?"}
F -->|"yes"| G["contains() / find()"]
Does this key exist?
Use contains to test for a key; it does not modify the value and does not throw:
json j = {{"name", "Mary"}, {"address", {{"city", "Berlin"}}}};
j.contains("name"); // true
j.contains("age"); // false
j.contains("city"); // false: contains() only looks at the top level
j["address"].contains("city"); // true
j.contains(json::json_pointer("/address/city")); // true: a JSON pointer tests a nested path in one call
If the value is needed afterwards, find tests and accesses with a single lookup:
if (auto it = j.find("name"); it != j.end())
{
std::cout << *it << '\n';
}
contains also returns true for a key whose value is null; use j.contains("k") && !j["k"].is_null() if a
null should count as missing. To read a value with a fallback instead, see value.
!!! warning "operator[] inserts missing keys"
Like `#!cpp std::map::operator[]`, the non-const [`operator[]`](unchecked_access.md) adds a `null` value if the key
is missing. Testing a key with it therefore *changes the object*:
```cpp
json j = {{"foo", 1}};
bool absent = j["bar"].is_null(); // true, but j is now {"bar": null, "foo": 1}
```
Use `contains`/`find` to test, and [`at`](checked_access.md) to access a value that must exist (it throws an
[`out_of_range`](../../home/exceptions.md#out-of-range) exception otherwise).