Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to overload the QDataStream &operator << and >> for third party libraries?

How to overload the QDataStream &operator << and >> for third party libraries?

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 4 Posters 6.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    robson-estek
    wrote on last edited by robson-estek
    #1

    lets say I want to implement the QDataStream operator for "std::string"

    QDataStream &operator<<(QDataStream &ds, const std::string &inObj)
    {
    	ds << QString::fromStdString(inObj);
    	return ds;
    }
    
    QDataStream &operator >> (QDataStream &ds, std::string &outObj)
    {
    	QString outElement;
    	ds >> outElement;
    	outObj = outElement.toStdString();
    	return ds;
    }
    
    QDataStream &operator<<(QDataStream &ds, const MyClass &inObj)
    {
    	ds << QVector<std::string>::fromStdVector(inObj.myVector);
    }
    

    if I compile this and try to stream a std::string stored inside a QVector I will get the following error:

    binary '<<': no operator found which takes a left-hand operand of type 'QDataStream'
    

    How can I make the QDataStream class see the operator that I overloaded for std::string?

    If I stream a std::string that in not included in a QVector then it will be streamed correctly.

    I'm just taking std::string as an example, but it could be any other class declared on a third party library

    raven-worxR 1 Reply Last reply
    0
    • R robson-estek

      lets say I want to implement the QDataStream operator for "std::string"

      QDataStream &operator<<(QDataStream &ds, const std::string &inObj)
      {
      	ds << QString::fromStdString(inObj);
      	return ds;
      }
      
      QDataStream &operator >> (QDataStream &ds, std::string &outObj)
      {
      	QString outElement;
      	ds >> outElement;
      	outObj = outElement.toStdString();
      	return ds;
      }
      
      QDataStream &operator<<(QDataStream &ds, const MyClass &inObj)
      {
      	ds << QVector<std::string>::fromStdVector(inObj.myVector);
      }
      

      if I compile this and try to stream a std::string stored inside a QVector I will get the following error:

      binary '<<': no operator found which takes a left-hand operand of type 'QDataStream'
      

      How can I make the QDataStream class see the operator that I overloaded for std::string?

      If I stream a std::string that in not included in a QVector then it will be streamed correctly.

      I'm just taking std::string as an example, but it could be any other class declared on a third party library

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @robson-estek
      where did you put this code?
      in a header file you include or in a cpp file?

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      R 1 Reply Last reply
      1
      • raven-worxR raven-worx

        @robson-estek
        where did you put this code?
        in a header file you include or in a cpp file?

        R Offline
        R Offline
        robson-estek
        wrote on last edited by robson-estek
        #3

        @raven-worx

        in the MyClass.h inside my namespace

        namespace myNamespace
        {
        class MyClass.h
        {
        ...
        		friend QDataStream &operator << (QDataStream &ds, const std::string &inObj);
        		friend QDataStream &operator >> (QDataStream &ds, std::string &outObj);
        friend QDataStream &operator<<(QDataStream &ds, const MyClass &inObj);
        ...
        }
        }
        

        and in the MyClass.cpp inside my namespace i've put the rest

        QDataStream &operator<<(QDataStream &ds, const MyClass &inObj)
        {
        	ds << QVector<std::string>::fromStdVector(inObj.myVector);
        }
        
        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #4
          • You need to declare the std::string operators in an header and include the header in MyClass.cpp
          • QVector<std::string>::fromStdVector is inefficient, it takes a deep copy, just serialise the size and each of the values separatley
          • you don't need to friend the std::string operator
          • global friends usually have the global scope expicited `friend QDataStream& (::operator<<) (QDataStream &ds, const MyClass &inObj);

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          R 1 Reply Last reply
          3
          • VRoninV VRonin
            • You need to declare the std::string operators in an header and include the header in MyClass.cpp
            • QVector<std::string>::fromStdVector is inefficient, it takes a deep copy, just serialise the size and each of the values separatley
            • you don't need to friend the std::string operator
            • global friends usually have the global scope expicited `friend QDataStream& (::operator<<) (QDataStream &ds, const MyClass &inObj);
            R Offline
            R Offline
            robson-estek
            wrote on last edited by robson-estek
            #5

            @VRonin

            thank you,

            I was thinking about doing what you said, but I hoped that there was a way more pleasent to the eye =).

            So to make std::vector< std::string > be recognized by the QDataStream, is declaring the operators << and >> with "std::vectorstd::string" as the parameter the only option?

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by VRonin
              #6

              No.

              stringserial.h

              QDataStream &operator<<(QDataStream &ds, const std::string &inObj);
              QDataStream &operator >> (QDataStream &ds, std::string &outObj);
              

              stringserial.cpp

              #include "stringserial.h"
              QDataStream &operator<<(QDataStream &ds, const std::string &inObj)
              {
              	ds << QString::fromStdString(inObj);
              	return ds;
              }
              
              QDataStream &operator >> (QDataStream &ds, std::string &outObj)
              {
              	QString outElement;
              	ds >> outElement;
              	outObj = outElement.toStdString();
              	return ds;
              }
              

              myclass.h

              namespace myNamespace{
              class MyClass{
              // other stuff
              std::vector<std::string> inObj;
              friend QDataStream& (::operator<<) (QDataStream &ds, const MyClass &inObj);
              friend QDataStream& (::operator>>) (QDataStream &ds, MyClass &inObj);
              };
              }
              QDataStream& operator<<(QDataStream &ds, const myNamespace::MyClass &inObj);
              QDataStream& operator>>(QDataStream &ds, myNamespace::MyClass &inObj);
              

              myclass.cpp

              #include "myclass.h"
              #include "stringserial.h"
              // other stuff
              QDataStream& operator<<(QDataStream &ds, const myNamespace::MyClass &inObj)
              {
              	ds << ststic_cast<quint32>(inObj.myVector.size());
              for(auto& vecElement : inObj.myVector)
              ds << vecElement;
              return ds;
              }
              QDataStream& operator>>(QDataStream &ds, myNamespace::MyClass &inObj)
              {
              quint32 tempSize
              	ds >> tempSize; 
              inObj.myVector.resize(tempSize);
              for(quint32 i=0;i<tempSize;++i)
              ds >> inObj.myVector[i];
              return ds;
              }
              

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              R 1 Reply Last reply
              2
              • VRoninV VRonin

                No.

                stringserial.h

                QDataStream &operator<<(QDataStream &ds, const std::string &inObj);
                QDataStream &operator >> (QDataStream &ds, std::string &outObj);
                

                stringserial.cpp

                #include "stringserial.h"
                QDataStream &operator<<(QDataStream &ds, const std::string &inObj)
                {
                	ds << QString::fromStdString(inObj);
                	return ds;
                }
                
                QDataStream &operator >> (QDataStream &ds, std::string &outObj)
                {
                	QString outElement;
                	ds >> outElement;
                	outObj = outElement.toStdString();
                	return ds;
                }
                

                myclass.h

                namespace myNamespace{
                class MyClass{
                // other stuff
                std::vector<std::string> inObj;
                friend QDataStream& (::operator<<) (QDataStream &ds, const MyClass &inObj);
                friend QDataStream& (::operator>>) (QDataStream &ds, MyClass &inObj);
                };
                }
                QDataStream& operator<<(QDataStream &ds, const myNamespace::MyClass &inObj);
                QDataStream& operator>>(QDataStream &ds, myNamespace::MyClass &inObj);
                

                myclass.cpp

                #include "myclass.h"
                #include "stringserial.h"
                // other stuff
                QDataStream& operator<<(QDataStream &ds, const myNamespace::MyClass &inObj)
                {
                	ds << ststic_cast<quint32>(inObj.myVector.size());
                for(auto& vecElement : inObj.myVector)
                ds << vecElement;
                return ds;
                }
                QDataStream& operator>>(QDataStream &ds, myNamespace::MyClass &inObj)
                {
                quint32 tempSize
                	ds >> tempSize; 
                inObj.myVector.resize(tempSize);
                for(quint32 i=0;i<tempSize;++i)
                ds >> inObj.myVector[i];
                return ds;
                }
                
                R Offline
                R Offline
                robson-estek
                wrote on last edited by
                #7

                @VRonin

                thank you again for your time, I did understood the concept of writing/reading the size of the vector first and then writing/reading the elements of the vector.

                But what I am interested, just to know if it is possible, I wanted something like

                QDataStream& operator<<(QDataStream &ds, const myNamespace::MyClass &inObj)
                {
                	ds << inObj.myStdStringVector;
                        return ds;
                }
                

                if I understood correctly, the only way to achieve that is by doing something like

                QDataStream& operator<<(QDataStream &ds, const std::vector<std::string> &inVector)
                {
                        ds << qInt32(inVector.size());
                	for(size_t i = 0; i<inVector.size(); i++)
                             ds << inVector[i];
                        return ds;
                }
                
                1 Reply Last reply
                1
                • D Offline
                  D Offline
                  DungeonLords
                  wrote on last edited by
                  #8

                  May be my example help you.

                  typedef struct my_struct{
                      my_struct(const quint32 my_i, const bool my_b):i{my_i}, b{my_b}{};
                      my_struct(){};
                      quint32 i{};
                      bool b{};
                  }my_struct_t;
                  
                  QDataStream &operator<<(QDataStream &out, const my_struct_t& s){
                      out << s.i << s.b;
                      return out;
                  }
                  
                  QDataStream &operator>>(QDataStream &in, my_struct_t& s){
                      in >> s.i >> s.b;
                      return in;
                  }
                  
                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved