0

How do I extract information of underlying datatype from nlohmann object? Since the values are stored as primitive datatypes in the json why don't it give the output like a and b below?

I see typedef as below for ordered json.

nlohmann::basic_json<nlohmann::ordered_map,std::vector, std::string, bool, std::int64_t, std::uint64_t, double>;

So it's clear the type of values it's storing(?).

int main()
{
  json js;
  js["key1"] = 1L;
  js["key2"]  = 0.111f;

  auto a = 1L;
  auto b = 0.111f;


  decltype(js["key1"]) x = js["key1"];
  decltype(js["key2"]) y = js["key2"];

  cout<<typeid(a).name()<<endl;
  cout<<typeid(b).name()<<endl;
  cout<<typeid(x).name()<<endl;
  cout<<typeid(y).name()<<endl;

}

Output:

l
f
N8nlohmann10basic_jsonINS_11ordered_mapESt6vectorNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEblmdSaNS_14adl_serializerES2_IhSaIhEEEE
N8nlohmann10basic_jsonINS_11ordered_mapESt6vectorNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEblmdSaNS_14adl_serializerES2_IhSaIhEEEE
Sreeraj Chundayil
  • 5,548
  • 3
  • 29
  • 68

1 Answers1

0

operator[] will return anlohmann::basic_json & type that is used to hold the value.

The output you are seeing is the mangled specialization of the nlohmann::basic_json template class that has been typedef'd for ordered JSON.

That is

nlohmann::basic_json<nlohmann::ordered_map,std::vector, std::string, bool, std::int64_t, std::uint64_t, double>;

corresponds to

N8nlohmann10basic_jsonINS_11ordered_mapESt6vectorNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEblmdSaNS_14adl_serializerES2_IhSaIhEEEE

So what happens when you use operator[] e.g. js["key1"] is that it returns a reference to that basic_json type specialization as that is how the storage works internally.

However, nlohmann also provides implicit conversions for stl types and so the example below would implicitly convert the nlohmann::basic_json types returned by operator[] in to the (original) numeric types

  auto a = 1L;
  auto b = 0.111f;

  long x = js["key1"];
  float y = js["key2"];

  cout<<typeid(a).name()<<endl;
  cout<<typeid(b).name()<<endl;
  cout<<typeid(x).name()<<endl;
  cout<<typeid(y).name()<<endl;

The implicit conversion is not restricted to converting it to the original type. E.g the following in which the original long is now converted to an int and the float to a double would also work

  js["key1"] = 1L;
  js["key2"]  = 0.111f;

  int x = js["key1"];
  double y = js["key2"];
C2P1
  • 397
  • 2
  • 4
  • 13