title: Using QDataStream to serialize custom class causes C2679 error
body: <p>I'm writing an application in which I need serialization to store some data in files. For serialization I want to use the <a href="http://doc.qt.io/qt-4.8/qdatastream.html" rel="nofollow noreferrer">QDataStream</a> class.</p>
  
  <p>I can't compile my code due to this compiler error:</p>
  
  <blockquote>
    <p>Error 1   error C2679: binary '&lt;&lt;' : 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</p>
  </blockquote>
  
  <p>See the relevant code below. Anyone knows what's going on here?</p>
  
  <p>There is a <a href="https://stackoverflow.com/questions/22979932/error-c2679-while-trying-to-serialize-qlist-of-custom-class-with-qdatastream">similar question</a> which didn't help me. When I follow the steps described there, I get this (similar) error:</p>
  
  <blockquote>
    <p>Error 1   error C2678: binary '&lt;&lt;' : 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</p>
  </blockquote>
  
  <hr>
  
  <p>This is my problem:</p>
  
  <p>What I want to serialize is a class called CMPProject.</p>
  
  <p>CMPProject holds</p>
  
  <ul>
  <li><code>CListModel* m_pData;</code></li>
  <li><code>QDateTime m_dateTimeCreated;</code></li>
  </ul>
  
  <p>This is basically what should be serialized.</p>
  
  <p>CMPProject has operators to stream its contents into a QDataStream.</p>
  
  <p><strong>MPProject.h:</strong></p>
  
  <pre><code>#ifndef _MPPROJECT_
  #define _MPPROJECT_
  
  #include &lt;QtCore/QString&gt;
  #include &lt;QtCore/QFile&gt;
  #include &lt;QtCore/QDateTime&gt;
  
  #include "ListModel.h"
  
  class CMPProject
  {
  public:
      // ...
  
      friend QDataStream&amp; operator &lt;&lt;(QDataStream&amp; stream, const CMPProject&amp; project);
      friend QDataStream&amp; operator &gt;&gt;(QDataStream&amp; stream, CMPProject&amp; project);
  
  private:
      static const quint32 m_streamHeader = 0x1329453;
      QFile* m_pFile;
      CListModel* m_pData;
      QDateTime m_dateTimeCreated;
  };
  
  #endif // _MPPROJECT_
  </code></pre>
  
  <p>The data stream operators in <strong>MPProject.cpp</strong>:</p>
  
  <pre><code>QDataStream&amp; operator &lt;&lt;(QDataStream&amp; stream, const CMPProject&amp; project)
  {
      return stream &lt;&lt; project.m_dateTimeCreated &lt;&lt; *(project.m_pData);
  }
  
  QDataStream&amp; operator &gt;&gt;(QDataStream&amp; stream, CMPProject&amp; project)
  {
      return stream &gt;&gt; project.m_dateTimeCreated &gt;&gt; *(project.m_pData);
  }
  </code></pre>
  
  <p><code>m_pData</code> is of type <code>CListModel</code>. <code>CListModel</code> contains the actual data stored as a <code>QList&lt;CListItem&gt;</code>.</p>
  
  <p>To serialize the CListModel I added the according operators in <strong>ListModel.h</strong>:</p>
  
  <pre><code>#ifndef _LISTMODEL_
  #define _LISTMODEL_
  
  #include &lt;QtCore/QAbstractListModel&gt;
  #include &lt;QtCore/QList&gt;
  #include &lt;QtCore/QStringList&gt;
  
  #include "ListItem.h"
  
  typedef QMap&lt;unsigned int, QString&gt; TValueMap;
  
  class CListModel : public QAbstractListModel
  {
  public:
      // ...
  
      template&lt;typename T&gt;
      friend void operator &lt;&lt;(QVariant&amp; data, const QList&lt;T&gt;&amp; target);
  
      template&lt;typename T&gt;
      friend void operator &gt;&gt;(const QVariant&amp; data, QList&lt;T&gt;&amp; target);
  
      friend QDataStream&amp; operator &lt;&lt;(QDataStream&amp; stream, const CListModel&amp; listModel);
      friend QDataStream&amp; operator &gt;&gt;(QDataStream&amp; stream, CListModel&amp; listModel);
  
  private:    
  
      QList&lt;CListItem&gt; m_items;
  };
  
  #endif // !_LISTMODEL_
  </code></pre>
  
  <p>and <strong>ListModel.cpp</strong>:</p>
  
  <pre><code>template&lt;typename T&gt;
  void operator &lt;&lt;(QVariant&amp; data, const QList&lt;T&gt;&amp; target)
  {
      QVariantList list;
      list.reserve(target.count());
      for (int i = 0; i &lt; target.count(); i++) {
          QVariant item;
          item &lt;&lt; target[i];
          list.append(item);
      }
      data = list;
  }
  
  template&lt;typename T&gt;
  void operator &gt;&gt;(const QVariant&amp; data, QList&lt;T&gt;&amp; target)
  {
      QVariantList list = data.toList();
      target.reserve(list.count());
      for (int i = 0; i &lt; list.count(); i++) {
          T item;
          list[i] &gt;&gt; item;
          target.append(item);
      }
  }
  
  QDataStream&amp; operator &lt;&lt;(QDataStream&amp; stream, const CListModel&amp; listModel)
  {
      // ERROR C2679 does not occur when I change this line to "return stream;"
      return stream &lt;&lt; listModel.m_items;
  }
  
  QDataStream&amp; operator &gt;&gt;(QDataStream&amp; stream, CListModel&amp; listModel)
  {
      return stream &gt;&gt; listModel.m_items;
  }
  </code></pre>
  
  <p>In order to serialize the contents of <code>listModel.m_items</code> (objects of type <code>CListItem</code>) I implemented the according operators in <strong>ListItem.h</strong>:</p>
  
  <pre><code>#ifndef _LISTITEM_
  #define _LISTITEM_
  
  #include &lt;QtCore/QString&gt;
  #include &lt;QtCore/QStringList&gt;
  #include &lt;QtCore/QDateTime&gt;
  #include &lt;QtCore/QVariantMap&gt;
  
  class CListItem
  {
  public:
      // ...
  
      friend void operator &lt;&lt;(QVariant&amp; data, const CListItem&amp; target);
      friend void operator &gt;&gt;(const QVariant&amp; data, CListItem&amp; target);
  private:
      QString m_name;
      QString m_domain;
      QString m_login;
      QString m_password;
      QDateTime m_LastModified;
  };
  
  #endif // !_LISTITEM_
  </code></pre>
  
  <p>and <strong>ListItem.cpp</strong>:</p>
  
  <pre><code>template&lt;typename T&gt;
  void operator &lt;&lt;(QVariant&amp; data, const T&amp; target)
  {
      data = QVariant::fromValue&lt;T&gt;(target);
  }
  
  template&lt;typename T&gt;
  void operator &gt;&gt;(const QVariant&amp; data, T&amp; target)
  {
      target = data.value&lt;T&gt;();
  }
  
  void operator &lt;&lt;(QVariant&amp; data, const CListItem&amp; target)
  {
      QVariantMap map;
      map["name"] &lt;&lt; target.m_name;
      map["domain"] &lt;&lt; target.m_domain;
      map["login"] &lt;&lt; target.m_login;
      map["password"] &lt;&lt; target.m_password;
      map["dateModified"] &lt;&lt; target.m_LastModified;
      data &lt;&lt; map;
  }
  
  void operator &gt;&gt;(const QVariant&amp; data, CListItem&amp; target)
  {
      QVariantMap map;
      data &gt;&gt; map;
      map["name"] &gt;&gt; target.m_name;
      map["domain"] &gt;&gt; target.m_domain;
      map["login"] &gt;&gt; target.m_login;
      map["password"] &gt;&gt; target.m_password;
      map["dateModified"] &gt;&gt; target.m_LastModified;
  }
  </code></pre>