Сохранение переменной класса enum в JSON

#c #json #qt #serialization #enums

#c #json #qt #сериализация #перечисления

Вопрос:

Я хочу сохранить некоторую информацию в формате JSON.
Рассмотрим следующий фрагмент кода. У меня ошибка в save() методе, в котором переменной типа enum class присваивается значение QJsonValue .

Как я могу использовать enum class в этой ситуации?
Спасибо

 class MyClass : public QObject
{
    Q_OBJECT

public:
    enum class Status { Undefined, S1, S2 };
    Q_ENUM(Status)

    explicit MyClass(QObject *parent = nullptr);

    void save(QString filename) {
        //...
        QJsonObject jsonObj;
        jsonObj["id"] = m_id;
        jsonObj["status"] = m_status;   //<-- Error: no known conversion from 'MyClass::Status' to 'const QJsonValue' for 1st argument
        //...

        //Save QJsonDocument into target file
    }

private:
    QString m_id;
    MyClass::Status m_status;
    //...
};
  

Примечание: Если я изменю enum class значение на old enum , этот код будет работать нормально. Но с enum class она не будет скомпилирована.

Больше информации: смотрите JSON Save Game Example в исходном коде Qt. У нее есть класс с именем Character , и у него есть традиционное enum имя ClassType . Попробуйте изменить enum на enum class . Это не сработает. Как заставить ее работать?

Комментарии:

1. С помощью enum переменные могут быть преобразованы в int . Но с enum class неясно, как это должно быть преобразовано — в строку? число? какой-то класс? Пожалуйста, уточните это.

2. Возможно, enum class это неподходящий инструмент для этой работы. Если у вас есть переменная, enum которую вы специально хотите преобразовать в int , то простое использование enum было бы просто замечательно. В противном случае вам, вероятно, потребуется предоставить способ преобразования вашего enum class в int / string / double и т. Д

3. enum class это новый подход и отличная замена традиционному enum , поэтому его предпочтительнее использовать.

Ответ №1:

Отсюда: https://en.cppreference.com/w/cpp/language/enum

Не существует неявных преобразований значений перечислителя с ограниченной областью действия в целочисленные типы, хотя static_cast может использоваться для получения числового значения перечислителя.

Итак, это должно сработать:

 class MyClass : public QObject
{
    Q_OBJECT

public:
    enum class Status { Undefined, S1, S2 };
    Q_ENUM(Status)

    explicit MyClass(QObject *parent = nullptr);

    void save(QString filename) {
        //...
        QJsonObject jsonObj;
        jsonObj["id"] = m_id;
        jsonObj["status"] = static_cast<int>(m_status);   //<-- Error: no known conversion from 'MyClass::Status' to 'const QJsonValue' for 1st argument
        //...

        //Save QJsonDocument into target file
    }

private:
    QString m_id;
    MyClass::Status m_status;
    //...
};
  

Комментарии:

1. Этот способ является более общим и, по-видимому, более производительным

Ответ №2:

Вы можете преобразовать свою переменную enum class в QVariant и присвоить ее QJsonValue :

 jsonObj["status"] = QVariant::fromValue(m_status).toJsonValue();