上文介绍了结构体(类)与JSON相互转换的基本操作步骤——http://t.csdnimg.cn/VQNa0
同事也提到了四个宏分为两类——侵入式,非侵入式。
struct People
{
std::string name;
int age;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(People, name, age)
// NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(People, name, age)
};
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT
NLOHMANN_DEFINE_TYPE_INTRUSIVE
侵入式在结构体(类)内部使用,因为侵入式宏会在编译时给结构体(类)生成两个to_json()和from_json();下面是json.hpp中关于两个侵入式宏的定义
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
struct People
{
std::string name;
int age;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(People, name, age)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT
非侵入式宏在结构体(类)外部使用,非侵入式宏会在编译时生成两个内敛函数to_json()和from_json();
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT
NLOHMANN_DEFINE_TYPE_INTRUSIVE
又分为两类 是否带有初始值
#include "iostream"
#include "myStruct.h"
#include "json.hpp"
using namespace std;
struct People
{
std::string name = "asd";
int age = 123;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(People, name, age)
};
// NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(People, name, age)
int main(void)
{
// string jsonStr = "{\"age\":24,\"name\":\"asd\"}";
string jsonStr = "{\"age\":24}";
nlohmann::json js = nlohmann::json::parse(jsonStr);
People me = js.get();
cout << "name::" << me.name << endl;
cout << "age::" << me.age << endl;
return 0;
}
带有初始值的宏能够在 反序列化(也就是json转换为结构体或者类)时,补全json字符串中缺少的成员值。例如上述代码中,解析的字符串中只有“age”,没有“name”。在执行get
上述代码执行结果:
name::asd
age::24
#include "iostream"
#include "json.hpp"
using namespace std;
struct People
{
std::string name;
int age;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(People, name, age)
};
// NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(People, name, age)
int main(void)
{
// string jsonStr = "{\"age\":24,\"name\":\"asd\"}";
string jsonStr = "{\"age\":24}";
nlohmann::json js = nlohmann::json::parse(jsonStr);
People me = js.get();
cout << "name::" << me.name << endl;
cout << "age::" << me.age << endl;
return 0;
}
该代码执行会报错
terminate called after throwing an instance of 'nlohmann::json_abi_v3_11_3::detail::out_of_range'
what(): [json.exception.out_of_range.403] key 'name' not found
使用不带默认值的宏时,必须保证json字符串包含所有宏中使用的变量。
以上就是四个宏的区别。