nlohmann::json 与 better_enum 的用法
nlohmann::json usage with better_enum
是否可以使用更好的枚举(https://github.com/aantron/better-enums) with nlohmann::json(https://github.com/nlohmann/json)?
我正在尝试将 integer/short 字段迁移到 better_enum 生成的 class。我确实尝试添加 to_json 和 from_json 方法,但我仍然在编译时收到。
error: static_assert failed due to requirement
'std::is_default_constructiblestudents::GRADE::value' "types must be
DefaultConstructible when used with get()"
这是我尝试使用的代码示例
Student.hpp
namespace students {
BETTER_ENUM(GRADE, short,
GRADE_1,
GRADE_2)
struct Student {
std::string name;
GRADE grade;
};
inline nlohmann::json get_untyped(const nlohmann::json &j, const char *property) {
if (j.find(property) != j.end()) {
return j.at(property).get<nlohmann::json>();
}
return {};
}
inline nlohmann::json get_untyped(const nlohmann::json &j, const std::string &property) {
return get_untyped(j, property.data());
}
void from_json(const nlohmann::json &j, students::GRADE &x);
void to_json(nlohmann::json &j, const students::GRADE &x);
void from_json(const nlohmann::json &j, students::Student &x);
void to_json(nlohmann::json &j, const students::Student &x);
inline void students::from_json(const nlohmann::json &j, GRADE &x) {
x = GRADE::_from_integral(j.at("grade").get<short>());
}
inline void students::to_json(nlohmann::json &j, const GRADE &x) {
j["grade"] = x._to_integral();
}
inline void from_json(const nlohmann::json &j, students::Student &x) {
x.name = j.at("name").get<std::string>();
x.grade = j.at("grade").get<GRADE>();
}
inline void to_json(nlohmann::json &j, const students::Student &x) {
j = nlohmann::json::object();
j["name"] = x.name;
j["grade"] = x.grade;
}
}
文件存储代码:
students::Student student1 = {"vs", students::GRADE::GRADE_1};
nlohmann::json jsonObject = student1;
std::ofstream studentFile("/Users/vs/Projects/test/data/students.json");
studentFile << std::setw(4) << jsonObject << std::endl;
是的。来自 nlohmann::json 的 documentation:
How can I use get() for non-default constructible/non-copyable types?
There is a way, if your type is MoveConstructible. You will need to specialize the adl_serializer as well, but with a special from_json overload.
在这种情况下,您可能需要这样的东西:
namespace nlohmann {
template<>
struct adl_serializer<students::GRADE> {
static students::GRADE from_json(const json &j) {
return students::GRADE::_from_integral(j.get<int>());
}
static void to_json(json &j, students::GRADE t) {
j = t._to_integral();
}
};
}
是否可以使用更好的枚举(https://github.com/aantron/better-enums) with nlohmann::json(https://github.com/nlohmann/json)?
我正在尝试将 integer/short 字段迁移到 better_enum 生成的 class。我确实尝试添加 to_json 和 from_json 方法,但我仍然在编译时收到。
error: static_assert failed due to requirement 'std::is_default_constructiblestudents::GRADE::value' "types must be DefaultConstructible when used with get()"
这是我尝试使用的代码示例
Student.hpp
namespace students {
BETTER_ENUM(GRADE, short,
GRADE_1,
GRADE_2)
struct Student {
std::string name;
GRADE grade;
};
inline nlohmann::json get_untyped(const nlohmann::json &j, const char *property) {
if (j.find(property) != j.end()) {
return j.at(property).get<nlohmann::json>();
}
return {};
}
inline nlohmann::json get_untyped(const nlohmann::json &j, const std::string &property) {
return get_untyped(j, property.data());
}
void from_json(const nlohmann::json &j, students::GRADE &x);
void to_json(nlohmann::json &j, const students::GRADE &x);
void from_json(const nlohmann::json &j, students::Student &x);
void to_json(nlohmann::json &j, const students::Student &x);
inline void students::from_json(const nlohmann::json &j, GRADE &x) {
x = GRADE::_from_integral(j.at("grade").get<short>());
}
inline void students::to_json(nlohmann::json &j, const GRADE &x) {
j["grade"] = x._to_integral();
}
inline void from_json(const nlohmann::json &j, students::Student &x) {
x.name = j.at("name").get<std::string>();
x.grade = j.at("grade").get<GRADE>();
}
inline void to_json(nlohmann::json &j, const students::Student &x) {
j = nlohmann::json::object();
j["name"] = x.name;
j["grade"] = x.grade;
}
}
文件存储代码:
students::Student student1 = {"vs", students::GRADE::GRADE_1};
nlohmann::json jsonObject = student1;
std::ofstream studentFile("/Users/vs/Projects/test/data/students.json");
studentFile << std::setw(4) << jsonObject << std::endl;
是的。来自 nlohmann::json 的 documentation:
How can I use get() for non-default constructible/non-copyable types?
There is a way, if your type is MoveConstructible. You will need to specialize the adl_serializer as well, but with a special from_json overload.
在这种情况下,您可能需要这样的东西:
namespace nlohmann {
template<>
struct adl_serializer<students::GRADE> {
static students::GRADE from_json(const json &j) {
return students::GRADE::_from_integral(j.get<int>());
}
static void to_json(json &j, students::GRADE t) {
j = t._to_integral();
}
};
}