Qt / C ++ Сериализует объект generi c в QSettings - PullRequest
1 голос
/ 23 марта 2020

У меня есть несколько случаев в моем приложении, где я хочу сохранить составной объект в QSettings:

template <typename T>
class AwsProperty
{
public:
    AwsProperty(T value, quint64 timestamp){
        m_data = value;
        m_timestamp = timestamp;
    }
    AwsProperty(){}
    T value(){return m_data;}
    void update(T value,quint64 timestamp){m_data = value; m_timestamp = timestamp;}
    quint64 timestamp(){return m_timestamp;}

    void toQDataStream(QDataStream &dstream){dstream << m_data << m_timestamp;}
    void fromQDataStream(QDataStream &dstream){dstream >> m_data >> m_timestamp;}
private:
    quint64 m_timestamp;
    T m_data;
};

typedef AwsProperty<qint32> AwsPropertyInt32;
Q_DECLARE_METATYPE(AwsPropertyInt32)
typedef AwsProperty<quint32> AwsPropertyUint32;
Q_DECLARE_METATYPE(AwsPropertyUint32)
typedef AwsProperty<bool> AwsPropertyBool;
Q_DECLARE_METATYPE(AwsPropertyBool)

cpp выглядит так:

template <typename T>
QDataStream& operator<<(QDataStream& out, const AwsProperty<T>& classObj){
{
    classObj.toQDataStream(out);
    return out;
}
template <typename T>
QDataStream& operator>>(QDataStream& in, const AwsProperty<T>& classObj){
    classObj.fromQDataStream(in);
    return in;
}

Я зарегистрировал их в моем основном:

  qRegisterMetaTypeStreamOperators<AwsPropertyInt32>("AwsPropertyInt32");
    qRegisterMetaTypeStreamOperators<AwsPropertyUint32>("AwsPropertyUint32");
    qRegisterMetaTypeStreamOperators<AwsPropertyBool>("AwsPropertyBool");

Я получаю ошибку:

/opt/XXXXXXXXXX/0.9.99/sysroots/cortexa9hf-neon-XXXXXX-linux-gnueabi/usr/include/QtCore/qmetatype.h:810: error: no match for ‘operator<<’ (operand types are ‘QDataStream’ and ‘const AwsProperty<int>’)
         stream << *static_cast<const T*>(t);
         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~

Кроме того, почему оператор потоковой передачи не определен для QDataStream и QString.

1 Ответ

1 голос
/ 23 марта 2020

Вы должны зарегистрировать операторов в системе метатипов, используя qRegisterMetaTypeStreamOperators до создания экземпляра QSettings.

Кроме того, константность операторов и fromQDataStream и toQDataStream методы немного неправильны (см. ссылку для точного необходимого прототипа).

РЕДАКТИРОВАТЬ:

Этот код работает для меня: Обратите внимание, что я изменил константу некоторых методов и переместите операторы в файл заголовка, поскольку они являются шаблонами.

awsproperty.h

#include <QDataStream>

template <typename T>
class AwsProperty
{
public:
    AwsProperty(T value, quint64 timestamp){
        m_data = value;
        m_timestamp = timestamp;
    }
    AwsProperty(){}
    T value(){return m_data;}
    void update(T value,quint64 timestamp){m_data = value; m_timestamp = timestamp;}
    quint64 timestamp(){return m_timestamp;}

    void toQDataStream(QDataStream &dstream) const {dstream << m_data << m_timestamp;}
    void fromQDataStream(QDataStream &dstream){dstream >> m_data >> m_timestamp;}
private:
    quint64 m_timestamp;
    T m_data;
};

template <typename T>
QDataStream& operator<<(QDataStream& out, const AwsProperty<T>& classObj) {
    classObj.toQDataStream(out);
    return out;
}

template <typename T>
QDataStream& operator>>(QDataStream& in, AwsProperty<T>& classObj) {
    classObj.fromQDataStream(in);
    return in;
}

typedef AwsProperty<qint32> AwsPropertyInt32;
Q_DECLARE_METATYPE(AwsPropertyInt32)
typedef AwsProperty<quint32> AwsPropertyUint32;
Q_DECLARE_METATYPE(AwsPropertyUint32)
typedef AwsProperty<bool> AwsPropertyBool;
Q_DECLARE_METATYPE(AwsPropertyBool)

main. cpp

#include "awsproperty.h"
#include <QSettings>
#include <QDebug>

int main(int argc, char *argv[])
{
    qRegisterMetaTypeStreamOperators<AwsPropertyInt32>("AwsPropertyInt32");
    qRegisterMetaTypeStreamOperators<AwsPropertyUint32>("AwsPropertyUint32");
    qRegisterMetaTypeStreamOperators<AwsPropertyBool>("AwsPropertyBool");
    QSettings set("/tmp/testsettings.conf");

    AwsPropertyInt32 a{-2, 100};
    set.setValue("property", QVariant::fromValue(a));
    auto val = set.value("property").value<AwsPropertyInt32>();
    qDebug() << val.value() << " " << val.timestamp();
}
...