Files
json/features/element_access/index.md
T
2026-10-26 21:24:35 +00:00

3.6 KiB

Element Access

There are many ways elements in a JSON value can be accessed:

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.

operator[] inserts missing keys

Like std::map::operator[], the non-const operator[] adds a null value if the key is missing. Testing a key with it therefore changes the object:

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 to access a value that must exist (it throws an out_of_range exception otherwise).

See also