I have the following function:
// get-function that can handle nullptr.
template <typename T>
static const T get(const nlohmann::json& json, const T& retOnNull = T())
{
return json.is_null() ? retOnNull : json.get<T>();
}
Then I call it like this:
nlohmann::json j;
// ...
// Load json from file into j
auto ret = get<std::string>(j["SomeKey"], "");
Now I would expect one of three things to happen:
json.exception.type_error.302
Instead I sometimes (randomly) get the json.exception.type_error.302
exception even though, in my case, "SomeKey" doesn't exist. I checked what happens at that point and the data sent into the get
function seems to be not null and of type 105 (which is an indication the data is undefined). So how can this call into this function yield undefined data? Is it something about the new json entry going out of scope due to the reference pointer? Why does it happen randomly and not consistently? Is this an invalid way of using a new key?
The code is invoking undefined behavior: https://json.nlohmann.me/api/basic_json/operator%5B%5D/#template-parameters
If the element with key key does not exist, the behavior is undefined and is guarded by a runtime assertion!
Use json::at()
instead so you get a proper error (by exception) when the key doesn't exist or a type mismatch was detected.
Alternatively, use json::contains()
to check if the key is legal to access before attempting to access it: https://json.nlohmann.me/api/basic_json/contains/
If j.contains(x) returns true for a key or JSON pointer x, then it is safe to call j[x].