c++ - 使用 QDataStream 序列化自定义类导致 C2679 错误

标签 c++ qt serialization qt4

我正在编写一个应用程序,我需要在其中序列化以将一些数据存储在文件中。对于序列化,我想使用 QDataStream类。

由于这个编译器错误,我无法编译我的代码:

Error 1 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const CListItem' (or there is no acceptable conversion) c:\qt\4.8.6\src\corelib\io\qdatastream.h 265

参见下面的相关代码。有人知道这里发生了什么吗?

有一个similar question这对我没有帮助。当我按照那里描述的步骤操作时,我得到这个(类似的)错误:

Error 1 error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'QDataStream' (or there is no acceptable conversion) c:\qt\4.8.6\src\corelib\io\qdatastream.h 265


这是我的问题:

我要序列化的是一个叫CMPProject的类。

CMP项目持有

  • CListModel* m_pData;
  • QDateTime m_dateTimeCreated;

这基本上就是应该序列化的内容。

CMPProject 有运算符将其内容流式传输到 QDataStream。

MPProject.h:

#ifndef _MPPROJECT_
#define _MPPROJECT_

#include <QtCore/QString>
#include <QtCore/QFile>
#include <QtCore/QDateTime>

#include "ListModel.h"

class CMPProject
{
public:
    // ...

    friend QDataStream& operator <<(QDataStream& stream, const CMPProject& project);
    friend QDataStream& operator >>(QDataStream& stream, CMPProject& project);

private:
    static const quint32 m_streamHeader = 0x1329453;
    QFile* m_pFile;
    CListModel* m_pData;
    QDateTime m_dateTimeCreated;
};

#endif // _MPPROJECT_

MPProject.cpp中的数据流操作符:

QDataStream& operator <<(QDataStream& stream, const CMPProject& project)
{
    return stream << project.m_dateTimeCreated << *(project.m_pData);
}

QDataStream& operator >>(QDataStream& stream, CMPProject& project)
{
    return stream >> project.m_dateTimeCreated >> *(project.m_pData);
}

m_pData类型为 CListModel . CListModel包含存储为 QList<CListItem> 的实际数据.

为了序列化 CListModel,我在 ListModel.h 中添加了相应的运算符:

#ifndef _LISTMODEL_
#define _LISTMODEL_

#include <QtCore/QAbstractListModel>
#include <QtCore/QList>
#include <QtCore/QStringList>

#include "ListItem.h"

typedef QMap<unsigned int, QString> TValueMap;

class CListModel : public QAbstractListModel
{
public:
    // ...

    template<typename T>
    friend void operator <<(QVariant& data, const QList<T>& target);

    template<typename T>
    friend void operator >>(const QVariant& data, QList<T>& target);

    friend QDataStream& operator <<(QDataStream& stream, const CListModel& listModel);
    friend QDataStream& operator >>(QDataStream& stream, CListModel& listModel);

private:    

    QList<CListItem> m_items;
};

#endif // !_LISTMODEL_

ListModel.cpp:

template<typename T>
void operator <<(QVariant& data, const QList<T>& target)
{
    QVariantList list;
    list.reserve(target.count());
    for (int i = 0; i < target.count(); i++) {
        QVariant item;
        item << target[i];
        list.append(item);
    }
    data = list;
}

template<typename T>
void operator >>(const QVariant& data, QList<T>& target)
{
    QVariantList list = data.toList();
    target.reserve(list.count());
    for (int i = 0; i < list.count(); i++) {
        T item;
        list[i] >> item;
        target.append(item);
    }
}

QDataStream& operator <<(QDataStream& stream, const CListModel& listModel)
{
    // ERROR C2679 does not occur when I change this line to "return stream;"
    return stream << listModel.m_items;
}

QDataStream& operator >>(QDataStream& stream, CListModel& listModel)
{
    return stream >> listModel.m_items;
}

为了序列化listModel.m_items的内容(类型为 CListItem 的对象)我在 ListItem.h 中实现了相应的运算符:

#ifndef _LISTITEM_
#define _LISTITEM_

#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QDateTime>
#include <QtCore/QVariantMap>

class CListItem
{
public:
    // ...

    friend void operator <<(QVariant& data, const CListItem& target);
    friend void operator >>(const QVariant& data, CListItem& target);
private:
    QString m_name;
    QString m_domain;
    QString m_login;
    QString m_password;
    QDateTime m_LastModified;
};

#endif // !_LISTITEM_

ListItem.cpp:

template<typename T>
void operator <<(QVariant& data, const T& target)
{
    data = QVariant::fromValue<T>(target);
}

template<typename T>
void operator >>(const QVariant& data, T& target)
{
    target = data.value<T>();
}

void operator <<(QVariant& data, const CListItem& target)
{
    QVariantMap map;
    map["name"] << target.m_name;
    map["domain"] << target.m_domain;
    map["login"] << target.m_login;
    map["password"] << target.m_password;
    map["dateModified"] << target.m_LastModified;
    data << map;
}

void operator >>(const QVariant& data, CListItem& target)
{
    QVariantMap map;
    data >> map;
    map["name"] >> target.m_name;
    map["domain"] >> target.m_domain;
    map["login"] >> target.m_login;
    map["password"] >> target.m_password;
    map["dateModified"] >> target.m_LastModified;
}

最佳答案

我修好了。

问题是我没有运算符(operator)将我的 QList 放入 QDataStream。但是我定义了包装器来将我的列表存储在 QVariant 中,所以(当然)我应该使用它们。

QDataStream& operator <<(QDataStream& stream, const CListModel& listModel)
{
    QVariant var;
    var << listModel.m_items;
    return stream << var;
}

QDataStream& operator >>(QDataStream& stream, CListModel& listModel)
{
    QVariant var;
    stream >> var;

    var >> listModel.m_items;

    return stream;
}

关于c++ - 使用 QDataStream 序列化自定义类导致 C2679 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33857528/

相关文章:

c++ - 在 1 条语句中将自定义函数作为模板参数传递

C++欧拉问题14程序卡住

qt - 使用 qmake 链接静态库时如何提供链接器选项?

c++ - 尝试在 Raspberry Pi 上运行交叉编译的 Qt 时出现 "Illegal instruction"(Windows)

c# - 使用序列化维护对象关系映射

C++ 制作特定大小的文件

c++ - 为 STL 容器传递模板化迭代器

C++/QT - QFileDialog::getOpenFileName 过滤器 *.xml 禁用名称中包含日文字符的文件

c# - 序列化有序集成员

c++ - 如何通过 COM 发送列表