Unsolved How to overload the QDataStream &operator << and >> for third party libraries?
-
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
-
@robson-estek
where did you put this code?
in a header file you include or in a cpp file? -
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); }
-
- 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);
- You need to declare the
-
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?
-
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; }
-
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; }