c++nlohmann-json

Shouldn't assigning a string to a nlohmann::json object implicitely parse the json in the string?


I don't understand why this small program asserts. Both j and jj are fully parsed json objects that should be equivalent, but apparently they are not.

As far as I understood json j = json::parse(jsonstr) and json j = jsonstr should do the same thing.

If not, what does json jj = jsonstr do?

#include <iostream>
#include <cassert>
#include "nlohmann/json.hpp"

using json = nlohmann::json;

std::string get_string(const json& j, const std::string& key, const std::string& default_val = "N/A")
{
  return j.contains(key) && j[key].is_string() ? j[key].get<std::string>() : default_val;
}

int main() {
  std::string jsonstr =
R"(
{
    "error": {
        "code": 401,
        "message": "Request had invalid authentication credentials",
        "errors": [
            {
                "message": "Invalid Credentials",
                "domain": "global"
            }
        ],
        "status": "UNAUTHENTICATED"
    },
    "id" : "123"
}
)";

  json j = json::parse(jsonstr);     // j is now a fully parsed json object
  auto id1 = get_string(j, "id", "");
  assert(id1 == "123");    // this works as expected

  json jj = jsonstr;    // jj is now also a fully parsed json object equivalent to j
  auto id2 = get_string(jj, "id", "");    // after this line "id2" contains "" instead of "123"
  assert(id2 == "123");   // asserts here
}

Link on Godbolt


Solution

  • As far as I understood json j = json::parse(jsonstr) and json j = jsonstr should do the same thing.

    No, the former parses the string to return an object in you case, whereas the later returns an (unparsed) string.

    You might print both j and jj to see the difference: Demo

    j = {"error":{"code":401,"errors":[{"domain":"global","message":"Invalid Credentials"}],"message":"Request had invalid authentication credentials","status":"UNAUTHENTICATED"},"id":"123"}
    jj = "\n{\n    \"error\": {\n        \"code\": 401,\n        \"message\": \"Request had invalid authentication credentials\",\n        \"errors\": [\n            {\n                \"message\": \"Invalid Credentials\",\n                \"domain\": \"global\"\n            }\n        ],\n        \"status\": \"UNAUTHENTICATED\"\n    },\n    \"id\" : \"123\"\n}\n"