Details
-
Suggestion
-
Resolution: Unresolved
-
Not Evaluated
-
None
-
6.5.2
-
None
Description
Typically, the data member class of an implicitly shared class is more or less a list of data members. Consider the example in https://doc.qt.io/qt-6/qshareddatapointer.html:
class EmployeeData : public QSharedData { public: EmployeeData() : id(-1) { } EmployeeData(const EmployeeData &other) : QSharedData(other), id(other.id), name(other.name) { } ~EmployeeData() { } int id; QString name; };
The least error-prone way to implement equality and comparison operators would be to add
bool operator==(const EmployeeData& other) const = default;
Once QString supports spaceships, we could also do
std::strong_ordering operator<=>(const EmployeeData& other) const = default;
This won't work because
Object of type 'const EmployeeData ' cannot be compared because its 'operator==' is implicitly deleted
I can use a workaround by defining the operator for the base class locally:
namespace { // Enable comparison for data classes derived from QSharedData bool operator==(const QSharedData& d1, const QSharedData& d2) { Q_UNUSED(d1) Q_UNUSED(d2) return true; } }
I am aware that declaring an operator== on QSharedData that always returns true (despite QSharedData holding a QAtomicInt) may formally be considered wrong. But I wonder what use use comparing the QAtomicInt would serve, and what protection a non-existing comparison operator offers.
EDIT: Alternative workaround is to create an intermediate class derived from QSharedData like so:
class CompareEnabledShareData : public QSharedData { bool operator==(const CompareEnabledShareData&) const { return true; } }; class EmployeeData : public CompareEnabledShareData { //... };