c++11:nlohmann::json advanced use ordered_json

nlohmann::json The source code of nlohmann/json is written based on the C++11 standard. The whole source code is a file nlohmann/json.hpp, which is very convenient to reference. About the basic use of nlohmann/json official website( https://github.com/nlohmann/json )There is a more detailed introduction on. I won't repeat it here. This article mainly introduces some extension functions and important but not well understood features that I use nlohmann/json in addition to the basic use of nlohmann/json.

ordered_json

Let's take a look at a simple example of nlohmann/json call: nlohmann_json_test1.cpp

#include <iostream>
#include "nlohmann/json.hpp"
using namespace nlohmann;
int main()
{
    json j;
    j["tom"] = "hello";
    j["jerry"] = "world";
    std::cout << "j : " << j.dump(4) << std::endl;
}

The output is:

j : {
    "jerry": "world",
    "tom": "hello"
}

Although we first add "tom=hello" to the JSON object, the field names are sorted when we actually output JSON. Instead, the entry "tom": "hello" is output after "jerry": "world".

Why? Let's first talk about the basic overview of nlohmann/json Reading the source code of nlohmann/json, you can know that the whole nlohmann/json project is designed based on C++11 template technology, in which many template technologies provided by C++11 are used. It can be said that it is a classic application case of C + + template programming, from which I also learned a lot of template programming skills. Moreover, nlohmann::json is the main class used in nlohmann/json. It is actually a template class nlohmann:: basic_ Special case implementation of json, nlohmann:: Basic_ All json fields in json are actually saved in K-V mapping form (Map) objects, while nlohmann::basic_json uses std::map as the data object to save the K-V mapping by default See:

template<template<typename U, typename V, typename... Args> class ObjectType =
         std::map,
         template<typename U, typename... Args> class ArrayType = std::vector,
         class StringType = std::string, class BooleanType = bool,
         class NumberIntegerType = std::int64_t,
         class NumberUnsignedType = std::uint64_t,
         class NumberFloatType = double,
         template<typename U> class AllocatorType = std::allocator,
         template<typename T, typename SFINAE = void> class JSONSerializer =
         adl_serializer,
         class BinaryType = std::vector<std::uint8_t>>
class basic_json;

std::map is a template class provided by STL, which sorts K. So the result of the above example appears.

If you don't care about this order in your application, you don't have to read this article. In the scenario where I use nlohmann/json, I pay close attention to this order. I hope the field order of the output JSON is consistent with the order in which I add the fields. I don't want nlohmann/json to sort me.

What can I do?

I went to the official website of nlohmann/json and found that it has been upgraded many times since I used version 3.7.3. Now the new version is 3.10.4. nlohmann/json has added an nlohmann:: basic from 3.9.0gavc_ JSON implementation class ordered_json, this class can keep the order of inserting key s. The following is the description of ordered in json.hpp_ JSON description

/*!
@brief ordered JSON class

This type preserves the insertion order of object keys.

@since version 3.9.0
*/
using ordered_json = basic_json<nlohmann::ordered_map>;

}  // namespace nlohmann

It's timely rain. Update the version decisively, Then change the type of the j variable in the previous code to ordered_json is OK nlohmann_json_test2.cpp

#include <iostream>
#include "nlohmann/json.hpp"
using namespace nlohmann;
int main()
{
    ordered_json j;
    j["tom"] = "hello";
    j["jerry"] = "world";
    std::cout << "j : " << j.dump(4) << std::endl;
}

The output order is changed, that is, the order in which key s are added:

j : {
    "tom": "hello",
    "jerry": "world"
}

Posted on Mon, 29 Nov 2021 08:13:48 -0500 by subnet_rx