Json in C++

Here’s the translation of the JSON example from Go to C++, presented in Markdown format suitable for Hugo:

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

// We'll use these two structs to demonstrate encoding and
// decoding of custom types below.
struct Response1 {
    int page;
    std::vector<std::string> fruits;
};

// Only public members will be encoded/decoded in JSON.
struct Response2 {
    int page;
    std::vector<std::string> fruits;
};

// Custom to_json and from_json functions for Response1
void to_json(json& j, const Response1& r) {
    j = json{{"Page", r.page}, {"Fruits", r.fruits}};
}

void from_json(const json& j, Response1& r) {
    j.at("Page").get_to(r.page);
    j.at("Fruits").get_to(r.fruits);
}

// Custom to_json and from_json functions for Response2
void to_json(json& j, const Response2& r) {
    j = json{{"page", r.page}, {"fruits", r.fruits}};
}

void from_json(const json& j, Response2& r) {
    j.at("page").get_to(r.page);
    j.at("fruits").get_to(r.fruits);
}

int main() {
    // First we'll look at encoding basic data types to
    // JSON strings. Here are some examples for atomic
    // values.
    json j_bool = true;
    std::cout << j_bool.dump() << std::endl;

    json j_int = 1;
    std::cout << j_int.dump() << std::endl;

    json j_float = 2.34;
    std::cout << j_float.dump() << std::endl;

    json j_string = "gopher";
    std::cout << j_string.dump() << std::endl;

    // And here are some for slices and maps, which encode
    // to JSON arrays and objects as you'd expect.
    std::vector<std::string> slcD = {"apple", "peach", "pear"};
    json j_slc = slcD;
    std::cout << j_slc.dump() << std::endl;

    std::map<std::string, int> mapD = {{"apple", 5}, {"lettuce", 7}};
    json j_map = mapD;
    std::cout << j_map.dump() << std::endl;

    // The JSON library can automatically encode your
    // custom data types. It will use the custom to_json
    // functions we defined earlier.
    Response1 res1D = {1, {"apple", "peach", "pear"}};
    json j_res1 = res1D;
    std::cout << j_res1.dump() << std::endl;

    // You can use the custom from_json functions to customize
    // the decoded JSON key names. Check the definition of
    // Response2 above to see an example of such functions.
    Response2 res2D = {1, {"apple", "peach", "pear"}};
    json j_res2 = res2D;
    std::cout << j_res2.dump() << std::endl;

    // Now let's look at decoding JSON data into C++
    // values. Here's an example for a generic data
    // structure.
    std::string str = R"({"num":6.13,"strs":["a","b"]})";
    json j = json::parse(str);

    // We can access the values in the decoded JSON directly.
    double num = j["num"];
    std::cout << num << std::endl;

    // Accessing nested data is straightforward.
    std::string str1 = j["strs"][0];
    std::cout << str1 << std::endl;

    // We can also decode JSON into custom data types.
    // This has the advantages of adding additional
    // type-safety to our programs.
    str = R"({"page": 1, "fruits": ["apple", "peach"]})";
    j = json::parse(str);
    Response2 res = j.get<Response2>();
    std::cout << res.page << std::endl;
    std::cout << res.fruits[0] << std::endl;

    // In the examples above we always used strings as
    // intermediates between the data and JSON representation.
    // We can also stream JSON encodings directly to std::ostream
    // like std::cout or even file streams.
    json d = {{"apple", 5}, {"lettuce", 7}};
    std::cout << d << std::endl;

    return 0;
}

This C++ code demonstrates JSON encoding and decoding using the nlohmann/json library, which is a popular JSON library for C++. The code covers similar concepts as the original Go example:

  1. Encoding basic data types to JSON
  2. Encoding slices (vectors in C++) and maps to JSON
  3. Encoding custom data types to JSON
  4. Decoding JSON into generic data structures
  5. Decoding JSON into custom data types
  6. Streaming JSON to output

To use this code, you’ll need to install the nlohmann/json library. You can do this via a package manager or by downloading the single header file from the GitHub repository.

When compiling, make sure to link against the necessary libraries and use C++11 or later:

$ g++ -std=c++11 json_example.cpp -o json_example
$ ./json_example

This will output the JSON representations and decoded values, similar to the original Go example.

Note that while Go has built-in support for JSON, C++ typically relies on external libraries for JSON handling. The nlohmann/json library provides a convenient and intuitive API that’s somewhat similar to Go’s encoding/json package.