C++ uses jsoncpp to write code optimization to improve human friendliness

1. Background Notes

Daily use jsoncpp When creating a Json, it is often necessary to create a child json, assign a value to the child json, and then save it to the parent json. This code structure is inconsistent with human logic, making it difficult to write, read, and understand.

2. Optimized Discovery

For the first few days cpp-httplib When you see a lot of lambda callback functions in your code, it greatly improves the simplicity of your code. When you use jsonCpp today, you are very unhappy about creating objects before assigning them to save, so you have greatly improved the friendliness of humans after you start to transform them.

3. Inspiration Creation

If you can write a function directly after "json['key']=" to return "Json::Value", then you can add it in a human-friendly order and you no longer need to initialize it before adding the object. The lambda function can be used on demand and written to the right value position is appropriate, but the type required for the left value is not a function, so you can call a function that returns the left value type and fill in the lambda expression you want to call with parameters, which will do both. So an intermediate function is constructed.

The key part of the code below is the second line of this intermediate function, which calls the incoming lambda function to return the type required for the left value:

    std::function<Json::Value()>runs = [&]()->Json::Value { return Json::Value(); };  // Functions that need to be passed in/constructed
    auto func = [&](std::function<Json::Value()>f){ return f(); };   // Key Functions
    Json::Value val = func(runs); // Can be called normally

Note: std::function, auto, lambda all require C++11 and above. You can add - std=c++11 parameter at compile time

4. Code Practice

1. json to generate

{
    "graden": "six",
    "leaders": [
        "sam",
        "tim"
    ],
    "students": [
        {
            "name": "andy",
            "sex": "boy"
        },
        {
            "name": "alice",
            "sex": "girl"
        }
    ],
    "teacher": "tom"
}

2. Traditional construction methods

The hierarchy is not clear, the order is not intuitive, and code folding is not easy in the IDE.

void classJson(){
    // Traditional methods of constructing json
    Json::Value jClass;
    jClass["graden"]  = "six";

    jClass["teacher"] = "tom";

    Json::Value jLeader;
    jLeader.append("sam");
    jLeader.append("tim");
    jClass["leaders"] = jLeader;

    Json::Value jStudents;
    Json::Value jItem;
    jItem["name"] = "andy";
    jItem["sex"]  = "boy";
    jStudents.append(jItem);
    jItem.clear();
    jItem["name"] = "alice";
    jItem["sex"]  = "girl";
    jStudents.append(jItem);
    jClass["students"] = jStudents;
    
    // Output generated string
    Json::FastWriter write;
    cout << write.write(jClass) << endl;
}

3. Optimized code

Folding code still fits human intuition.

void specialJson(){
    // Clever way to construct json//c++11:std::function/lambda/auto
    std::function<Json::Value()>runs = [&]()->Json::Value { return Json::Value(); };  // Functions that need to be passed in/constructed
    auto func = [&](std::function<Json::Value()>f){ return f(); };   // Key Functions
    Json::Value val = func(runs); // Can be called normally
    
    // Specific implementation
    Json::Value jSpecial;
    jSpecial["graden"]  = "six";
    jSpecial["teacher"] = "tom";
    jSpecial["leaders"] = func([&]()->Json::Value {
        Json::Value jLeaders;
        jLeaders.append("sam");
        jLeaders.append("tim");
        return jLeaders;
    });
    jSpecial["students"] = func([&]()->Json::Value {
        Json::Value jStudents;
        jStudents.append(func([&]()->Json::Value {
            Json::Value jAndy;
            jAndy["name"] = "andy";
            jAndy["sex" ] = "boy";
            return jAndy;
        }));
        jStudents.append(func([&]()->Json::Value {
            Json::Value jALice;
            jALice["name"] = "alice";
            jALice["sex"]  = "girl";
            return jALice;
        }));
        return jStudents;
    });
    
    // Output generated string
    Json::FastWriter write;
    cout << write.write(jSpecial) << endl;
}

4. Output Results

{"graden":"six","leaders":["sam","tim"],"students":[{"name":"andy","sex":"boy"},{"name":"alice","sex":"girl"}],"teacher":"tom"}

{"graden":"six","leaders":["sam","tim"],"students":[{"name":"andy","sex":"boy"},{"name":"alice","sex":"girl"}],"teacher":"tom"}

5. Full code

//  main.cpp
//  Created by Guoiaoang on 2021/12/6.

#include <iostream>
#include "json/json.h"
using namespace std;

/*
{
  "graden": "six",
  "teacher": "tom",
  "leaders": [
    "sam",
    "tim"
  ],
  "students": [
    {
      "name": "andy",
      "sex": "boy"
    },
    {
      "name": "alice",
      "sex": "girl"
    }
  ]
}
*/

void classJson(){
    // Traditional methods of constructing json
    Json::Value jClass;
    jClass["graden"]  = "six";

    jClass["teacher"] = "tom";

    Json::Value jLeader;
    jLeader.append("sam");
    jLeader.append("tim");
    jClass["leaders"] = jLeader;

    Json::Value jStudents;
    Json::Value jItem;
    jItem["name"] = "andy";
    jItem["sex"]  = "boy";
    jStudents.append(jItem);
    jItem.clear();
    jItem["name"] = "alice";
    jItem["sex"]  = "girl";
    jStudents.append(jItem);
    jClass["students"] = jStudents;
    
    // Output generated string
    Json::FastWriter write;
    cout << write.write(jClass) << endl;
}

void specialJson(){
    // Clever way to construct json//c++11:std::function/lambda/auto
    std::function<Json::Value()>runs = [&]()->Json::Value { return Json::Value(); };  // Functions that need to be passed in/constructed
    auto func = [&](std::function<Json::Value()>f){ return f(); };   // Key Functions
    Json::Value val = func(runs); // Can be called normally
    
    // Specific implementation
    Json::Value jSpecial;
    jSpecial["graden"]  = "six";
    jSpecial["teacher"] = "tom";
    jSpecial["leaders"] = func([&]()->Json::Value {
        Json::Value jLeaders;
        jLeaders.append("sam");
        jLeaders.append("tim");
        return jLeaders;
    });
    jSpecial["students"] = func([&]()->Json::Value {
        Json::Value jStudents;
        jStudents.append(func([&]()->Json::Value {
            Json::Value jAndy;
            jAndy["name"] = "andy";
            jAndy["sex" ] = "boy";
            return jAndy;
        }));
        jStudents.append(func([&]()->Json::Value {
            Json::Value jALice;
            jALice["name"] = "alice";
            jALice["sex"]  = "girl";
            return jALice;
        }));
        return jStudents;
    });
    
    // Output generated string
    Json::FastWriter write;
    cout << write.write(jSpecial) << endl;
}

int main(int argc, const char * argv[]) {
    classJson();
    specialJson();
    getchar();
    return EXIT_SUCCESS;
}

5. Optimizing Directions

This function should be constructed using templates to improve the generality of the code.

6. Reference Use

1.cpp-httplib
2.jsoncpp

Tags: C++ JSON Lambda C++11

Posted on Mon, 06 Dec 2021 16:10:01 -0500 by jeankaleb