nlohmann 最优秀的C++序列化工具库 详细入门教程(转)

C++使用nlohmann json教程

使用指南:

1.include

#include <nlohmann/json.hpp>

// for convenience

using json = nlohmann::json;

2.compile with(编译选项)

-std=c++11

3.makefile CMakeLists.txt

# CMakeLists.txt find_package(nlohmann_json 3.2.0 REQUIRED) ...

add_library(foo ...) ...

target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)

使用方法:

json示例:

{
  "pi": 3.141,
  "happy": true,
  "name": "Niels",
  "nothing": null,
  "answer": {
    "everything": 42
  },
  "list": [1, 0, 2],
  "object": {
    "currency": "USD",
    "value": 42.99
  }
}

对应的代码如下:

// create an empty structure (null)
json j;

// add a number that is stored as double (note the implicit conversion of j to an object)
j["pi"] = 3.141;

// add a Boolean that is stored as bool
j["happy"] = true;

// add a string that is stored as std::string
j["name"] = "Niels";

// add another null object by passing nullptr
j["nothing"] = nullptr;

// add an object inside the object
j["answer"]["everything"] = 42;

// add an array that is stored as std::vector (using an initializer list)
j["list"] = { 1, 0, 2 };

// add another object (using an initializer list of pairs)
j["object"] = { {"currency", "USD"}, {"value", 42.99} };

//另一种代码写法:

// instead, you could also write (which looks very similar to the JSON above)
json j2 = {
  {"pi", 3.141},
  {"happy", true},
  {"name", "Niels"},
  {"nothing", nullptr},
  {"answer", {
    {"everything", 42}
  }},
  {"list", {1, 0, 2}},
  {"object", {
    {"currency", "USD"},
    {"value", 42.99}
  }}
};

序列化:

// 从字符串文本创建对象
json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;

// 比原始文本更好的方式
auto j2 = R"(
  {
    "happy": true,
    "pi": 3.141
  }
)"_json;

// 显示的解析
auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }");


// 显式的转换为字符串
std::string s = j.dump();    // {\"happy\":true,\"pi\":3.141}

// 打印显示序列化结果
// 将空格转换为缩进
std::cout << j.dump(4) << std::endl;
// {
//     "happy": true,
//     "pi": 3.141
// }

从文件读取/保存到文件:

// 读取JSON文件
std::ifstream i("file.json");
json j;
i >> j;

// 将json数据结构保存为文件
std::ofstream o("pretty.json");
o << std::setw(4) << j << std::endl;

类型转换:

namespace ns {
    // 下面简单的结构介绍一个人
    struct person {
        std::string name;
        std::string address;
        int age;
    };
}

一般的方法:

ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};

// 转换为JSON:将每个值copy到JSON对象中。
json j;
j["name"] = p.name;
j["address"] = p.address;
j["age"] = p.age;

// ...

// 从JSON转换:从JSON对象中拷贝每个值。
ns::person p {
    j["name"].get<std::string>(),
    j["address"].get<std::string>(),
    j["age"].get<int>()
};

更好的方法(nlohmann应用):

using nlohmann::json;

namespace ns {
    void to_json(json& j, const person& p) {
        j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}};
    }

    void from_json(const json& j, person& p) {
        j.at("name").get_to(p.name);
        j.at("address").get_to(p.address);
        j.at("age").get_to(p.age);
    }
} // namespace ns


// create a person
ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60};

// conversion: person -> json
json j = p;

std::cout << j << std::endl;
// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}

// conversion: json -> person
auto p2 = j.get<ns::person>();

// that's it
assert(p == p2);

就这样!使用类型调用 json 构造函数时将自动调用自定义to_json方法。同样,当调用 get<your_type>() 或get_to(your_type&)时,将调用from_json方法。

如何转换第三方类型?

namespace nlohmann {

template <typename T>
struct adl_serializer {
    static void to_json(json& j, const T& value) {
        // calls the "to_json" method in T's namespace
    }

    static void from_json(const json& j, T& value) {
        // same thing, but with the "from_json" method
    }
};

}

如何将 get() 用于非默认可构造/不可复制类型?

struct move_only_type {
    move_only_type() = delete;
    move_only_type(int ii): i(ii) {}
    move_only_type(const move_only_type&) = delete;
    move_only_type(move_only_type&&) = default;

    int i;
};

namespace nlohmann {
    template <>
    struct adl_serializer<move_only_type> {
        // 注意:返回类型不再是"void",该方法仅采用一个参数
        static move_only_type from_json(const json& j) {
            return {j.get<int>()};
        }

        // 注意!你必须提供一个to_json方法!否则,您将无法将move_only_type转换为 json,

        //因为您完全专有adl_serializer该类型。
        static void to_json(json& j, move_only_type t) {
            j = t.i;
        }
    };
}

例子:

#pragma once

#include <nlohmann/json.hpp>
using json = nlohmann::json;
#include "sensor_data.h"
#include "rfid_info.h"

namespace nlohmann {
    template <>
    struct adl_serializer<SensorData> {
        // note: the return type is no longer 'void', and the method only takes
        // one argument
        static SensorData from_json(const json& j) {
            SensorData sensor_data;
            sensor_data.sensor_identify = j.at("SensorIdentify").get<string>();
            return sensor_data;
        }

        // Here's the catch! You must provide a to_json method! Otherwise you
        // will not be able to convert move_only_type to json, since you fully
        // specialized adl_serializer on that type
        static void to_json(json& j, SensorData t) {
            j = json{ {"SensorIdentify",t.sensor_identify},{"SensorType",t.sensor_type },{"Data",t.data} };
        }
    };
    template <>
    struct adl_serializer<RfidInfo> {
        // note: the return type is no longer 'void', and the method only takes
        // one argument
        static RfidInfo from_json(const json& j) {
            RfidInfo rfid_info;
            rfid_info.identify = j.at("Identify").get<string>();
            return rfid_info;
        }

        // Here's the catch! You must provide a to_json method! Otherwise you
        // will not be able to convert move_only_type to json, since you fully
        // specialized adl_serializer on that type
        static void to_json(json& j, RfidInfo t) {
            j = json{ { "Identify",t.identify },{ "Position",0 } };
        }
    };
}

二进制格式(BSON)

// create a JSON value
json j = R"({"compact": true, "schema": 0})"_json;

// serialize to BSON
std::vector<std::uint8_t> v_bson = json::to_bson(j);

// 0x1B, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6F, ...

// roundtrip
json j_from_bson = json::from_bson(v_bson);

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值