c++qtoperator-overloadingoperator-keywordqmap

Implemented `operator<` still gives error - no match for 'operator <' (opereate types are const StorageFile' and 'const StorageFile')


I have a custom struct named StorageFile which contains some information about a file do be stored in a database.

class StorageFile : public QObject {
     Q_OBJECT

  public:
     int ID = -1;
     QString filename;
     QString relativeLocation;
     MediaType type;
     QDateTime dateLastChanged;
     quint64 size;
     QString sha256;
     //...

     explicit StorageFile(QObject* parent = nullptr);
     StorageFile(const StorageFile& other);
     StorageFile& operator= (const StorageFile& other);
     bool operator< (const StorageFile& storageFile);      < --------- implemented operator
     bool operator== (const StorageFile& storageFile);

     //...
}

I am adding these StorageFile objects to a QMap, and the QMap requires the operator< to be implemented - which I have. The compiler gives the following error:

F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtCore/qmap.h:71:17: error: no match for 'operator<' (operand types are 'const StorageFile' and 'const StorageFile')
     return key1 < key2;
            ~~~~~^~~~~~

Even though I have implemented the required operator, why does it still give this error?


Update

Adding the definition for the operator:

StorageFile.cpp

//...
bool StorageFile::operator <(const StorageFile& storageFile)
{
     return size > storageFile.size;
}
//...

After modifying the offending line to:

bool operator< (const StorageFile& storageFile) const;

An it complained with:

path\to\project\libs\storagefile.h:33: error: candidate is: bool StorageFile::operator<(const StorageFile&) const
      bool operator< (const StorageFile& storageFile) const;
           ^~~~~~~~

Solution

as @cijien mentioned, make sure the operator< has the const keyword & the definition is updated accordingly:

The StorageFile.h

 bool operator< (const StorageFile& storageFile) const;

and StorageFile.cpp

bool StorageFile::operator<(const StorageFile& storageFile) const
{
     return size > storageFile.size;
}

(note the const keywords at the end of both)


Solution

  • Your operator< is incorrect. To allow < to work when the left hand side operand is a const object, you need to const-qualify the member operator< as well:

    bool operator< (const StorageFile& storageFile) const;
                                                //  ^^^^^
    

    Note that a map would usually require that const keys can be compared with <, which is what the error message is suggesting.

    This is generally how operator< should be implemented as a member. You can also write a non-member operator< if that works for your use case.

    Edit: Looking at your code, it is unclear whether you have defined operator< at all. Obviously, you need to do that, but it still must be const-qualified.