error overloading compare operator for struct
-
Hi all -
I'm trying to create a comparison operator for a struct I've defined. I cut out most of the code for brevity; here's what produces the error:
// EquipmentItem must be a struct; // if we make it a QObject-based class, we lose the assignment operator. struct EquipmentItem { Q_GADGET public: QString m_name; }; bool operator==(const EquipmentItem &lhs, const EquipmentItem &rhs) { bool rc = false; if (lhs.m_name == rhs.m_name) rc = true; return rc; }
I'm getting the following errors at build time:
C:\Qt\6.4.2\mingw_64\include\QtCore\qmetaobject.h:176: error: 'EquipmentItem' does not name a type C:\Qt\6.4.2\mingw_64\include\QtCore\qmetaobject.h:179: error: no match for 'operator==' (operand types are 'const QMetaMethod' and 'const QMetaMethod')
So...
- can someone tell me what I'm doing wrong?
- is this even the best approach, or should I be defining the operator within the struct? I've seen examples with both approaches, but I can't get either to work.
Thanks...
-
Hi @mzimmers.
you are not really overloadingoperator==
. You have to define it within the struct (or implement it directly). For that purpose you have to have in mind thatthis
will be an implicit argument within the struct, so you only have to mention it in an implementation out of line.
That said, something like this should ferry you across the river:a) direct implementation
// EquipmentItem must be a struct; // if we make it a QObject-based class, we lose the assignment operator. struct EquipmentItem { Q_GADGET public: QString m_name; bool operator==(const EquipmentItem &left) const { return left.m_name == m_name; } };
b) definition and implementation out of line
// EquipmentItem must be a struct; // if we make it a QObject-based class, we lose the assignment operator. struct EquipmentItem { Q_GADGET public: QString m_name; bool operator==(const EquipmentItem &left) const; }; // somewhere else bool EquipmentItem::operator==(const EquipmentItem &left, const EquipmentItem &right) const { return left.m_name == right.m_name; }
-
Works fine for me:
#include <QtCore> struct EquipmentItem { Q_GADGET public: QString m_name; }; bool operator==(const EquipmentItem& lhs, const EquipmentItem& rhs) { bool rc = false; if (lhs.m_name == rhs.m_name) rc = true; return rc; } int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); EquipmentItem item; return 0; } #include "main.moc"
Please provide a minimal, compilable example.
-
@mzimmers said in error overloading compare operator for struct:
bool operator==(const EquipmentItem &lhs, const EquipmentItem &rhs)
{
bool rc = false;
if (lhs.m_name == rhs.m_name)
rc = true;
return rc;
}??????????
bool operator==(const EquipmentItem &rhs) { bool rc = false; if (this->m_name == rhs.m_name) rc = true; return rc; }
-
Hi @mzimmers.
you are not really overloadingoperator==
. You have to define it within the struct (or implement it directly). For that purpose you have to have in mind thatthis
will be an implicit argument within the struct, so you only have to mention it in an implementation out of line.
That said, something like this should ferry you across the river:a) direct implementation
// EquipmentItem must be a struct; // if we make it a QObject-based class, we lose the assignment operator. struct EquipmentItem { Q_GADGET public: QString m_name; bool operator==(const EquipmentItem &left) const { return left.m_name == m_name; } };
b) definition and implementation out of line
// EquipmentItem must be a struct; // if we make it a QObject-based class, we lose the assignment operator. struct EquipmentItem { Q_GADGET public: QString m_name; bool operator==(const EquipmentItem &left) const; }; // somewhere else bool EquipmentItem::operator==(const EquipmentItem &left, const EquipmentItem &right) const { return left.m_name == right.m_name; }
-
@Christian-Ehrlicher kindly and competently reminded me that
operator==
has to be const.
Thanks! (previous post edited for correction) -
Well, I can't provide a compilable example, but here are my files:
equipmentitem.h:
#ifndef EQUIPMENTITEM_H #define EQUIPMENTITEM_H #include <QObject> // EquipmentItem must be a struct; // if we make it a QObject-based class, we lose the assignment operator. struct EquipmentItem { Q_GADGET public: QString m_name; bool operator==(const EquipmentItem &rhs); }; #endif // EQUIPMENTITEM_H
equipmentitem.cpp:
bool EquipmentItem::operator==(const EquipmentItem &rhs) { bool rc = false; do { if (m_name != rhs.m_name) continue; rc = true; } while (false); return rc; }
Trying to build with this in a CMake project yields the errors above.
I notice that the errors are exposed in my qmetaobject.h file, so I deleted my build directory and re-ran CMake, etc. with no change in results.
-
As always - simplify your program until it's short enough so we can compile it here or the error goes away - the task of a programmer.
-
Change the definition to
bool operator==(const EquipmentItem &rhs) const;
...and the implementation to my proposal from the previous post.
-
Change the definition to
bool operator==(const EquipmentItem &rhs) const;
...and the implementation to my proposal from the previous post.
@Axel-Spoerl I'm confused - which implementation should I be using? When I try this:
bool EquipmentItem::operator==(const EquipmentItem &lhs, const EquipmentItem &rhs) const { ...
I get an additional error:
C:\Users\Michael.Zimmers\Qt_projects\nga_demo\equipmentitem.cpp:28: error: Overloaded 'operator==' must be a binary operator (has 3 parameters)
EDIT:
I can get rid of that error by coding this instead:
bool EquipmentItem::operator==(const EquipmentItem &rhs) const {
But the original errors remain.
EDIT 2:
I took Christian's suggestion, and put those files in an otherwise empty project, and it builds without error. So, I guess this is no longer a C++ issue.
Thanks for all the assistance.
-
The { at the end was my typo.
Best to use one of the options I have proposed above. -
OK, so I found the problem, and the operator overload was a red herring (though I was indeed doing it wrong).
It turns out that in my experimentation with the overload operator, I accidently changed this line in the qmetaobject.h file:
// from friend bool operator ==(const QMetaMethod &lhs, const QMetaMethod &m2) // to friend EquipmentItem operator ==(const QMetaMethod &lhs, const QMetaMethod &m2)
Oops. I think this happened when I mindlessly clicked on a light bulb icon...I should have been more careful.
To find this, I just needed to look at the complete error messages (which I didn't post here) a little more carefully.
Two lessons from this:
- My Qt installation should probably be readonly, yes?
- Might be better to use github rather than the installer for downnloading Qt, so that I can easily see when a file got changed.
Anyway, thanks again for looking.
-
Thanks for sharing!
Regarding 1) and 2) - git is my preference.
(Comes with a handy advantage: When you find a way to make Qt even better, you can just push it ;-) -
OK, so I found the problem, and the operator overload was a red herring (though I was indeed doing it wrong).
It turns out that in my experimentation with the overload operator, I accidently changed this line in the qmetaobject.h file:
// from friend bool operator ==(const QMetaMethod &lhs, const QMetaMethod &m2) // to friend EquipmentItem operator ==(const QMetaMethod &lhs, const QMetaMethod &m2)
Oops. I think this happened when I mindlessly clicked on a light bulb icon...I should have been more careful.
To find this, I just needed to look at the complete error messages (which I didn't post here) a little more carefully.
Two lessons from this:
- My Qt installation should probably be readonly, yes?
- Might be better to use github rather than the installer for downnloading Qt, so that I can easily see when a file got changed.
Anyway, thanks again for looking.
@mzimmers said in error overloading compare operator for struct:
My Qt installation should probably be readonly, yes?
Definitely NO. It might be OK to lock down some areas, but I just finished chasing down a problem due to making some android templates readonly -- it caused my builds to break. Just a cautionary note...