Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Overloading QDataStream operators



  • I am overloading QDataStream operator with my custom class.

    #include <QCoreApplication>
    #include <QDataStream>
    #include<QVector>
    
    class MsgPointAttribute{
    public:
        double pointValue;
    };
    
    class MsgPoint{
    public:
        QVector<MsgPointAttribute> pointAtributes;
        // Additional info like point color can be appended.
    };
    
    class MsgPointCloud{
    public:
        QString pointType;
        quint32 cloudWidth;
        quint32 cloudHeight;
        quint32 pointsCount;
        QVector<MsgPoint> points;
        // Additional info like cloud properties can be added here can be added here
    };
    
    class MsgPointCloudDataResponse{
    
    private :
    
    public:
    
        quint64 recievedTimestamp;
        QString responseChannelName;
        QString responseDeviceName;
        QString cloudName;
        QVector<MsgPointCloud> pointClouds;
    
    
    //    friend QDataStream &operator <<(QDataStream &out, const MsgPointCloudDataResponse &other);
    
    };
    
    // you need this if you want to use your type with QVariant
    Q_DECLARE_METATYPE(MsgPointCloudDataResponse)
    
    QDataStream &operator <<(QDataStream &out, const MsgPointCloudDataResponse &other){
    
    //    // Register your custom type with Stream operators.
    //    qRegisterMetaTypeStreamOperators<qreal>("qreal");
    
        int pointCloudsCount = other.pointClouds.count();
    
        // Looping through the list of point clouds.
        for(int i = 0; i < pointCloudsCount; ++i)
        {
            out << other.pointClouds[i].pointType << other.pointClouds[i].cloudWidth <<
                   other.pointClouds[i].cloudHeight << other.pointClouds[i].pointsCount;
    
            int pointCount = other.pointClouds[i].pointsCount;
    
            for(int j = 0; j < pointCount; ++j)
            {
                int  iPointAttrCount = other.pointClouds[i].points[j].pointAtributes.count();
    
                for(int k = 0; k < iPointAttrCount; ++k){
                    out << other.pointClouds[i].points[j].pointAtributes[k].pointValue;
                }
            }
        }
    
        return out;
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        // Register your custom type with Stream operators.
        qRegisterMetaTypeStreamOperators<MsgPointCloudDataResponse>("MsgPointCloudDataResponse");
    
        return a.exec();
    }
    

    I get the following error and what am I missing.

    C:\Qt\Qt5.7.0\5.7\msvc2015_64\include\QtCore/qmetatype.h(777): error C2679: binary '>>': no operator found which takes a right-hand operand of type 'MsgPointCloudDataResponse' (or there is no acceptable conversion)


  • Moderators

    @Uday-More

    I havn't done that myself yet, but it seems like,

    qRegisterMetaTypeStreamOperators requieres you to define/overload << as well as >> to also get the data back !?

    and you only defined << in the code you showed.



  • @J.Hilk Thanks so much. It solved the above problem.
    But now eventually i get another error as described below

    moc_appcontroller.obj : error LNK2005: "class QDataStream & __cdecl operator<<(class QDataStream &,class MsgPointCloudDataResponse const &)" (??6@YAAEAVQDataStream@@AEAV0@AEBVMsgPointCloudDataResponse@@@Z) already defined in appcontroller.obj
    moc_appcontroller.obj : error LNK2005: "class QDataStream & __cdecl operator>>(class QDataStream &,class MsgPointCloudDataResponse &)" (??5@YAAEAVQDataStream@@AEAV0@AEAVMsgPointCloudDataResponse@@@Z) already defined in appcontroller.obj

    Note : In appcontroller class I've just used the statement
    qRegisterMetaTypeStreamOperators<MsgPointCloudDataResponse>("MsgPointCloudDataResponse");



  • Move the implementation of the datastream operators to a .cpp file rather than having it in the header



  • @VRonin said in Overloading QDataStream operators:

    Move the implementation of the datastream operators to a .cpp file rather than having it in the header

    Thanks. This is the solution.

    1. Overload both operators
    2. Have the overloading code in a cpp file.

Log in to reply