使用QDataStream序列化自定义class导致C2679错误
Using QDataStream to serialize custom class causes C2679 error
我正在编写一个应用程序,我需要在其中序列化以将一些数据存储在文件中。对于序列化,我想使用 QDataStream class.
由于这个编译器错误,我无法编译我的代码:
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.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.8.6\src\corelib\io\qdatastream.h 265
这是我的问题:
我要连载的是一个class叫做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<<
参数重载:QDataStream &
和 QList<CListItem> const&
。在参考文献 here and here 中,没有任何记录。
第二个错误解决了这个问题,但也应该提到 QList<CListItem>
参数。这是完整的错误消息吗?
基本上,你应该使用这个:
QDataStream& operator <<(QDataStream& stream, const CListModel& listModel)
{
for(auto const& item : listModel.m_items)
stream << item; // write elements one by one
return stream;
}
此模板可能适用于多种类型(或类似于 Pretty-print C++ STL containers 的内容):
template <typename Stream, typename Containter>
Stream& operator <<(Stream& stream, const Containter& container)
{
for(auto const& item : container)
stream << item;
return stream;
}
您的代码无需更改您定义的 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;
}
我正在编写一个应用程序,我需要在其中序列化以将一些数据存储在文件中。对于序列化,我想使用 QDataStream class.
由于这个编译器错误,我无法编译我的代码:
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.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.8.6\src\corelib\io\qdatastream.h 265
这是我的问题:
我要连载的是一个class叫做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<<
参数重载:QDataStream &
和 QList<CListItem> const&
。在参考文献 here and here 中,没有任何记录。
第二个错误解决了这个问题,但也应该提到 QList<CListItem>
参数。这是完整的错误消息吗?
基本上,你应该使用这个:
QDataStream& operator <<(QDataStream& stream, const CListModel& listModel)
{
for(auto const& item : listModel.m_items)
stream << item; // write elements one by one
return stream;
}
此模板可能适用于多种类型(或类似于 Pretty-print C++ STL containers 的内容):
template <typename Stream, typename Containter>
Stream& operator <<(Stream& stream, const Containter& container)
{
for(auto const& item : container)
stream << item;
return stream;
}
您的代码无需更改您定义的 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;
}