c++qtqhashqset

QSet append custom Object


I have the following class

class Test{
    int a;
    int b;
};

and all that I want is to have a QSet<Test> where I will insert some Test objects.

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    QSet<Test> setTest;
    setTest.insert(Test());
    return QCoreApplication::exec();
}

The problem is that I'm getting the following error for some reason and I don't know why or how can I fix it.

C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(118): error C2665: 'qHash': none of the 24 overloads could convert all the argument types C:\Qt\5.14.2\msvc2017_64\include\QtCore/qlocale.h(62): note: could be 'uint qHash(const QLocale &,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qregexp.h(56): note: or
'uint qHash(const QRegExp &,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(108): note: or 'uint qHash(std::nullptr_t,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(105): note: or 'uint qHash(QLatin1String,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(104): note: or 'uint qHash(const QBitArray &,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(103): note: or 'uint qHash(QStringView,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(101): note: or 'uint qHash(const QStringRef &,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(100): note: or 'uint qHash(const QString &,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(98): note: or 'uint qHash(const QByteArray &,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(97): note: or 'uint qHash(const QChar,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(95): note: or 'uint qHash(long double,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(93): note: or 'uint qHash(double,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(92): note: or 'uint qHash(float,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(91): note: or 'uint qHash(qint64,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(87): note: or 'uint qHash(quint64,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(86): note: or 'uint qHash(long,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(80): note: or 'uint qHash(ulong,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(79): note: or 'uint qHash(int,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(78): note: or 'uint qHash(uint,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(77): note: or 'uint qHash(short,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(76): note: or 'uint qHash(ushort,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(75): note: or 'uint qHash(signed char,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(74): note: or 'uint qHash(uchar,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(73): note: or 'uint qHash(char,uint) noexcept' C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(118): note: while trying to match the argument list '(const T)' with [ T=Test ] C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(117): note: see reference to function template instantiation 'uint qHash(const T &,uint) noexcept()' being compiled with [ Key=Test, T=Test ] C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhash.h(946): note: while compiling class template member function 'QHashNode<Key,T> **QHash<Key,T>::findNode(const Key &,uint *) const' with [ Key=Test, T=QHashDummyValue ] C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhash.h(790): note: see reference to function template instantiation 'QHashNode<Key,T> **QHash<Key,T>::findNode(const Key &,uint *) const' being compiled with [ Key=Test, T=QHashDummyValue ] C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhash.h(786): note: while compiling class template member function 'QHash<T,QHashDummyValue>::iterator QHash<T,QHashDummyValue>::insert(const Key &,const QHashDummyValue &)' with [ T=Test, Key=Test ] C:\Qt\5.14.2\msvc2017_64\include\QtCore/qset.h(208): note: see reference to function template instantiation 'QHash<T,QHashDummyValue>::iterator QHash<T,QHashDummyValue>::insert(const Key &,const QHashDummyValue &)' being compiled with [ T=Test, Key=Test ] C:\Qt\5.14.2\msvc2017_64\include\QtCore/qset.h(257): note: see reference to class template instantiation 'QHash<T,QHashDummyValue>' being compiled with [ T=Test ] C:\Users\vlad.dumitru\CLionProjects\Test\main.cpp(11): note: see reference to class template instantiation 'QSet' being compiled C:\Qt\5.14.2\msvc2017_64\include\QtCore/qhashfunctions.h(118): error C2056: illegal expression NMAKE : fatal error U1077: 'C:\PROGRA~2\MICROS~2\2017\BUILDT~1\VC\Tools\MSVC\1416~1.270\bin\Hostx64\x64\cl.exe' : return code '0x2' Stop. NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\HostX64\x64\nmake.exe"' : return code '0x2' Stop. NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\HostX64\x64\nmake.exe"' : return code '0x2' Stop. NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\HostX64\x64\nmake.exe"' : return code '0x2' Stop.

Does any of you know how can I fix this?

UPDATE:

class Test {
    int a;
    int b;

    bool operator==(const Test &e1) const {
        return e1.a == a && e1.b == b;
    }

    uint qHash(const Test &key, uint seed) {
        return qHash(key.a, seed) ^ key.b;
    }
};

I did write those 2 functions that I need but I'm getting a new error now:

error C2664: 'uint Test::qHash(const Test &,uint)': cannot convert argument 1 from 'const int' to 'const Test &'

I cant call the qHash(key.a, seed) because "Reference to type 'const Test' could not bind to an lvalue of type 'const int'"


Solution

  • QSet is implemented as a QHash, therefore you must implement the operator==() in your class and a qHash() function in the same namespace of your class.
    It'll overload the global qHash() and can have one of these signatures

    uint qHash(K key);
    uint qHash(const K &key);
    
    uint qHash(K key, uint seed);
    uint qHash(const K &key, uint seed);
    

    Qtherwise QSet won't be able to hash your data.

    You can look at the official example here
    https://doc.qt.io/qt-5/qhash.html#qhash


    This is the documentation page about QSet https://doc.qt.io/qt-5/qset.html#details
    I'm linking it here for completeness, but it is not clear about this requirement.