Array or object: how to use nlohmann::json for simple use cases?

3.3k Views Asked by At

I want to use the nlohmann JSON library in order to read options from a JSON file. Specifying options is optional, as reflected in the constructor in my code example. I'm assuming the JSON structure is an object in its root.

Unfortunately, I'm unable to use these options, because it is unclear to me how I can force the JSON structure to be an object. What is worse, merely initializing a member variable with a JSON object {} (magically?) turns it into an array [{}].

#include <cstdlib>
#include <iostream>
#include <nlohmann/json.hpp>

class Example {
public:
  explicit Example(const nlohmann::json& options = nlohmann::json::object())
    : m_options{options}
  {
    std::clog << options << '\n' << m_options << '\n';
  }
private:
  nlohmann::json m_options;
};

auto main() -> int
{
  Example x;
  Example y{nlohmann::json::object()};
  return EXIT_SUCCESS;
}

This results in the following output. Notice that we have to perform some ceremony in order to use an empty object as the default value (= empty settings), with = nlohmann::json::object(). Also notice that the settings object changes its type as soon as we initialize the member value (!):

{}
[{}]

My use use case is quite straightforward, but I'm unable to extract settings, unless I explicitly check whether the settings are an array or an object.

Another thing that worries me is that incorrect code compiles without warning, e.g., code in which I use x.value("y") on a JSON array x containing an object with key "y". Only at run time do I discover that I should have done x.at(0).value("y") instead.

In brief, the whole situation is quite surprising to me. I must be missing something / I must be using this library in an unintended way?

2

There are 2 best solutions below

0
On

nlohman is a very "modern" library, it uses a lot of features in C++. And that might make it harder to read and understand the code. But it is very flexible.

This short introduction might help Introduction to nlohmann json

Parse text to json object is done like

constexpr std::string_view stringJson = R"({"k1": "v1"})";
nlohmann::json j = nlohmann::json::parse( stringJson.begin(), stringJson.end() );
0
On

I ran in the same question, and my solution was to use the "implicit" way in which the library allows to assign values:

json x;
x["whatever"] = 3;

This doesn't answer your question in principle, but can maybe solve the use case.