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();
        }
    };
}