I'm writing an application in which I need serialization to store some data in files. For serialization I want to use the QDataStream class.
I can't compile my code due to this compiler error:
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
See the relevant code below. Anyone knows what's going on here?
There is a similar question which didn't help me. When I follow the steps described there, I get this (similar) error:
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
This is my problem:
What I want to serialize is a class called CMPProject.
CMPProject holds
- CListModel* m_pData;
- QDateTime m_dateTimeCreated;
This is basically what should be serialized.
CMPProject has operators to stream its contents into a 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_
The data stream operators in 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 is of type CListModel. CListModel contains the actual data stored as a QList<CListItem>.
To serialize the CListModel I added the according operators in 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_
and 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;
}
In order to serialize the contents of listModel.m_items (objects of type CListItem) I implemented the according operators in 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_
and 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;
}
 
     
    