Results 1 to 6 of 6

Thread: Problem with QDataStream operators

  1. #1
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Problem with QDataStream operators

    I have a class derived from QMap<> which I am using to store an association between two string values. I am having trouble with the serialization using QDataStream operator<<() and operator>>(). Here is the complete code for the class:

    Qt Code:
    1. // Header .h
    2.  
    3. #include <QMetaType>
    4. #include <QMap>
    5. #include <QString>
    6. #include <QVariant>
    7.  
    8.  
    9. class CClassColorMap
    10. : public QMap< QString, QVariant >
    11. {
    12. public:
    13. CClassColorMap();
    14. CClassColorMap( const CClassColorMap & rhs );
    15. virtual ~CClassColorMap();
    16. };
    17.  
    18. Q_DECLARE_METATYPE( CClassColorMap );
    19.  
    20. QDataStream & operator<<( QDataStream & stream, const CClassColorMap & classColors );
    21. QDataStream & operator>>( QDataStream & stream, CClassColorMap & classColors );
    22.  
    23.  
    24. // Implementation .cpp
    25.  
    26. #include "ClassColorMap.h"
    27. #include <QDataStream>
    28.  
    29. static CClassColorMap sClassColors;
    30. static bool sbRegistered = false;
    31.  
    32. CClassColorMap::CClassColorMap(void)
    33. : QMap< QString, QVariant >()
    34. {
    35. if ( !sbRegistered )
    36. {
    37. qRegisterMetaTypeStreamOperators< CClassColorMap >( "CClassColorMap" );
    38. sbRegistered = true;
    39. }
    40. }
    41.  
    42. CClassColorMap::CClassColorMap( const CClassColorMap & rhs )
    43. : QMap< QString, QVariant >()
    44. {
    45. if ( !sbRegistered )
    46. {
    47. qRegisterMetaTypeStreamOperators< CClassColorMap >( "CClassColorMap" );
    48. sbRegistered = true;
    49. }
    50.  
    51. *this = rhs;
    52. }
    53.  
    54. CClassColorMap::~CClassColorMap(void)
    55. {
    56. }
    57.  
    58. QDataStream & operator<<( QDataStream & stream, const CClassColorMap & classColors )
    59. {
    60. return operator<<( stream, (const QMap< QString, QVariant > &) classColors );
    61. }
    62.  
    63. QDataStream & operator>>( QDataStream & stream, CClassColorMap & classColors )
    64. {
    65. return operator>>( stream, (QMap< QString, QVariant > &) classColors );
    66. }
    To copy to clipboard, switch view to plain text mode 

    I am using this for QSettings. The issue is that the QDataStream operators are never called, either when retrieving the QSettings instance or when storing it. I verified this by settings breakpoints in the dbugger.

    I have other standalone custom classes (i.e. not derived from Qt base classes) that are used in the same QSettings, and that are declared and implemented in the identical fashion as the class above. The QDataStream operators are invoked just fine in those cases (again using the debugger to verify).

    Can anyone see what is wrong with the definition above? Or suggest a reason why this isn't working? The only critical difference is the QMap<> base class, but I don't understand why this could cause a problem.

    Update: I changed the class so it uses the QMap<> as a member variable rather than a base class. Now the stream operators are invoked. Why?
    Last edited by d_stranz; 3rd September 2014 at 00:47.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Problem with QDataStream operators

    I think this is because QDataStream already has an operator for serializing QMap which might come first before your specialized operator.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Problem with QDataStream operators

    I think this is because QDataStream already has an operator for serializing QMap which might come first before your specialized operator.
    That is my conclusion as well. This means that if I derive a class from QMap (or some other Qt class with defined serializing operators) and add more features to it, it will be impossible for me to serialize it using QDataStream operators. I would have thought that C++ would resolve any ambiguity by taking the more specialized class (mine) over the less specialized one (QMap), but maybe the qRegisterMetaTypeStreamOperators() method is the problem and not C++ type resolution rules.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Problem with QDataStream operators

    I think QMap is handled using a template function, maybe you should provide an explicit template specialization for this to work.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Problem with QDataStream operators

    maybe you should provide an explicit template specialization for this to work.
    Well, maybe, but the QMap<> base class for my CClassColorMap class is fully specialized. My QDataStream operators use my derived class, not QMap<>. Even if I provided a set of QDataStream operators for a fully specialized QMap<>, that still is not the same as the operators for my own class. If I had additional data members in my class that I wanted to serialize, operators for a fully specialized QMap<> wouldn't know about them.

    I think this is a defect in the lookup system for the QDataStream operators used in QMetaType. I haven't tried this with classes derived from other Qt base classes (like QString, f.e.) but my hunch is the same thing would happen. I'm under deadline pressure and unfortunately don't have the time to investigate.

    Edit: OK, I threw my deadline out the window and tested this using a class derived from QString. Everything I said above is completely wrong. At first, I thought that my string class QDataStream operators were not being called, so I changed the derived class to be a top level class with a QString member. The operators still weren't called. Huh?

    Then I realized that on import if QSettings doesn't find a value with the key you are asking for, it doesn't call operator>>() because there is nothing to serialize. When I exited the program (and saved the QSettings back out to the file), the operator<<() was called. I changed my string class back to being derived from QString, and sure enough, it works now on import too, because now there's a key in the QSettings file.

    I did the same for my QMap<> class - turned it back into a derived class of QMap<>, and it works now too. To make sure, I manually deleted all of the relevant entries from the QSettings file. On import, the operator>>() is not called, but on export operator<<() is called as it is supposed to be.

    My bad. Jumped to a wrong conclusion and because I was doing everything in the debugger and exiting before the export to the QSettings file occurred, I assumed a defect.

    I apologize for wasting everyone's time chasing a wrong conclusion.
    Last edited by d_stranz; 4th September 2014 at 22:12.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Problem with QDataStream operators

    At least we all learned something.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. The following user says thank you to wysota for this useful post:

    d_stranz (5th September 2014)

Similar Threads

  1. Regular Expression for Operators
    By parulkalra14 in forum Qt Programming
    Replies: 6
    Last Post: 7th January 2014, 10:36
  2. Define a QRegExp containing arithmetic operators
    By aaditya190 in forum Newbie
    Replies: 1
    Last Post: 4th December 2013, 11:38
  3. Store QVector to QDataStream problem
    By ruben.rodrigues in forum Newbie
    Replies: 1
    Last Post: 2nd August 2010, 09:27
  4. QDataStream class/struct & stream operators
    By darksaga in forum Qt Programming
    Replies: 1
    Last Post: 1st August 2008, 19:40
  5. Problem with QTcpSocket and QDataStream
    By Valheru in forum Qt Programming
    Replies: 4
    Last Post: 16th September 2006, 13:08

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.