Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

error: no match for ‘operator<<’ #113

Open
wxwok opened this issue Nov 12, 2023 · 5 comments
Open

error: no match for ‘operator<<’ #113

wxwok opened this issue Nov 12, 2023 · 5 comments

Comments

@wxwok
Copy link

wxwok commented Nov 12, 2023

Error Message:
In file included from /src/database/QxOrm/include/QxDao/QxDaoPointer.h:50,
                 from /src/database/QxOrm/include/QxCommon/QxAnyCastDynamic.h:50,
                 from /src/database/QxOrm/include/QxCollection/IxCollection.h:48,
                 from /src/database/QxOrm/include/QxCollection/QxCollection.h:54,
                 from /src/database/QxOrm/include/QxCommon/QxCache.h:49,
                 from /src/database/QxOrm/include/QxOrm.h:67,
                 from /src/database/model_view/include/../include/SolarSimulation_precompiled_header.model_view.gen.h:12,
                 from /src/database/model_view/include/SolarSimulation_all_include.model_view.gen.h:12,
                 from /src/qt/dialogcreateirratemp.cpp:1:
/src/database/QxOrm/include/QxSerialize/QDataStream/QxSerializeQDataStream_QSharedPointer.h: In instantiation of ‘QDataStream& operator<<(QDataStream&, const QSharedPointer<T>&) [with T = QCPAxisTicker]’:
/src/qt/6.6.0/gcc_64/include/QtCore/qmetatype.h:2370:10:   required from ‘static void QtPrivate::QDataStreamOperatorForType<T, <anonymous> >::dataStreamOut(const QtPrivate::QMetaTypeInterface*, QDataStream&, const void*) [with T = QSharedPointer<QCPAxisTicker>; bool <anonymous> = true]’
/src/qt/6.6.0/gcc_64/include/QtCore/qmetatype.h:2487:60:   required from ‘QtPrivate::QMetaTypeInterfaceWrapper<QSharedPointer<QCPAxisTicker> >::InterfaceType QtPrivate::QMetaTypeInterfaceWrapper<QSharedPointer<QCPAxisTicker> >::metaType’
/src/qt/6.6.0/gcc_64/include/QtCore/qmetatype.h:2582:12:   required from ‘constexpr const QtPrivate::QMetaTypeInterface* QtPrivate::qMetaTypeInterfaceForType() [with T = QSharedPointer<QCPAxisTicker>]’
/src/qt/6.6.0/gcc_64/include/QtCore/qmetatype.h:2615:61:   required from ‘static constexpr QMetaType QMetaType::fromType() [with T = QSharedPointer<QCPAxisTicker>]’
/src/qt/6.6.0/gcc_64/include/QtCore/qmetatype.h:1320:54:   required from ‘int qRegisterNormalizedMetaTypeImplementation(const QByteArray&) [with T = QSharedPointer<QCPAxisTicker>]’
/src/qt/6.6.0/gcc_64/include/QtCore/qmetatype.h:1352:56:   required from ‘int qRegisterNormalizedMetaType(const QByteArray&) [with T = QSharedPointer<QCPAxisTicker>]’
/src/qt/qcustomplot.h:1789:1:   required from here
/src/database/QxOrm/include/QxSerialize/QDataStream/QxSerializeQDataStream_QSharedPointer.h:54:20: error: no match for ‘operator<<’ (operand types are ‘QDataStream’ and ‘QCPAxisTicker’)
   54 |    if (t) { stream << (* t); }
      |             ~~~~~~~^~~~~~~~

In the above error message, the following global operator << needs all classes, who uses the QSharedPointer, should implement the operator << for the class QDataStream :
QDataStream & operator<< (QDataStream & stream, const QSharedPointer<T> & t)

As soon as the QxOrm.h is included and there is the macro Q_DECLARE_METATYPE in one source file, it will cause this issue. So I think it is better to hide the global operator << from the QxOrm.h. Maybe it could be moved to a single header which could be included when needed.

To reproduce the above error, just include the QxOrm.h and the qcustomplot.h which is from the repository: https://github.com/vasilyaksenov/QCustomPlot

@QxOrm
Copy link
Owner

QxOrm commented Nov 13, 2023

Hello,

I don't understand what is exactly the issue.
Maybe you can just provide the function required by the compiler ?

@wxwok
Copy link
Author

wxwok commented Nov 14, 2023

In this file:QxOrm/include/QxSerialize/QDataStream/QxSerializeQDataStream_QSharedPointer.h:50
there are two global operators:

template <typename T>
QDataStream & operator<< (QDataStream & stream, const QSharedPointer<T> & t)
{
   qint8 iIsNull = (t ? 0 : 1);
   stream << iIsNull;
   if (t) { stream << (* t); }             // it needs the type T to implement the operator <<()
   return stream;
}

template <typename T>
QDataStream & operator>> (QDataStream & stream, QSharedPointer<T> & t)
{
   qint8 iIsNull = 0;
   stream >> iIsNull;
   if (! iIsNull) { t = QSharedPointer<T>(new T()); stream >> (* t); }
   else { t = QSharedPointer<T>(); }
   return stream;
}

The reason for my issue is that type T doesn't implement QDataStream & operator<< (QDataStream & stream, T).

Since this header file is included by the QxOrm.h, the operator will be applied anywhere where it includes the QxOrm.h.
To try to understand the problem and reproduce the issue, you have to include the QxOrm.h and the header qcustomplot.h which comes from the project:https://github.com/vasilyaksenov/QCustomPlot. Just include them together, and you will reproduce it.

@QxOrm
Copy link
Owner

QxOrm commented Nov 15, 2023

If the compiler requires a specialization for the template QSharedPointer (or whatever type) : this is because somewhere in the code, this specialization is required : so operator>> or operator<< are used somewhere (maybe by QxOrm itself (?)).
Why do you not provide this speciailization ? Do you have a lot of types with this error ?

Maybe you have used the QCustomPlot class as a property of a persistent class registered in QxOrm context : in this case, you should go to the documentation here : https://www.qxorm.com/qxorm_en/manual.html#manual_460
And check the example MyPersistableType (you will see the operator>> and operator<< implementation).

@wxwok
Copy link
Author

wxwok commented Nov 16, 2023

I'm not using the QCustomPlot class as a property of a persistent class. The persistent class and the QCustomPlot are all members of a parent class, so I need include the persistent class and the QCustomPlot headers together. The persistent class is generated by the QEntityEditor.

Yes, you are right, I can resolve this problem by simply implementing the operator<<() and the operator>>() for QCustomPlot, but I don't need to persistent the QCustomPlot. also, the QCustomPlot is a third-party library, so it is not a good idea to work around it.

Since the QSharedPointer is used in the macro Q_OBJECT which is used in all Qt objects, it is used widely. So using the QxOrm in Qt non-persistent classes will cause a lot of compiling errors. I think the Q_OBJECT macro is a good idea as a way to make a persistent class. If a class needs work as a persistent class, we could put a macro in that class declaration.

I recommend moving the operators into the declaration of the persistent class headers.

@QxOrm
Copy link
Owner

QxOrm commented Nov 16, 2023

Thx for the details, this is interesting.

Maybe a solution could be to move :

#include <QxSerialize/QxSerializeQDataStream.h>
#include <QxSerialize/QDataStream/QxSerializeQDataStream_all_include.h>

From QxOrm.h file to QxOrm_Impl.h file.

QxOrm_Impl.h is included in each *.cpp files for each persistent classes (so not in headers).

I don't know if it will break something else, but you could try that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants