【问题标题】:nlohmann::json usage with better_enumnlohmann::json 使用 better_enum
【发布时间】:2021-08-31 20:20:13
【问题描述】:

是否可以在 nlohmann::json(https://github.com/nlohmann/json) 中使用更好的枚举(https://github.com/aantron/better-enums)?

我正在尝试将整数/短字段迁移到 better_enum 生成的类。我确实尝试在编译时添加 to_json 和 from_json 方法。

错误:static_assert 由于要求而失败 'std::is_default_constructiblestudents::GRADE::value' "类型必须是 与 get() 一起使用时 DefaultConstructible"

这是我尝试使用的代码示例

学生.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;

【问题讨论】:

    标签: c++ json enums nlohmann-json


    【解决方案1】:

    是的。来自 nlohmann::json 的 documentation:

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

    如果您的类型是 MoveConstructible,则有一种方法。您还需要专门化 adl_serializer,但要使用特殊的 from_json 重载。

    在这种情况下,您可能需要以下内容:

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

    【讨论】:

    • 感谢 unddoch,我之前什至尝试过类似的 impl,但我仍然看到如下错误:选择的构造函数在复制初始化中显式返回 {j.get()};
    • 或许可以试试return GRADE{k.get&lt;short&gt;()};
    • 没有运气错误:调用类'students::GRADE'的私有构造函数返回students::GRADE{j.get()};
    • 这行得通:返回学生::GRADE::_from_integral(j.get());感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    • 2016-11-01
    相关资源
    最近更新 更多