c++qtqhashqset

QSet: error with qHash and custom class


I want to create a QSet<Tag> that I want to use inside my program. Tag is my custom class.

When I build the code I obtain gcc errors regarding the qHash overloading:

Exercise.cpp.o
In file included from /opt/Qt/5.5/gcc_64/include/QtCore/qglobal.h:74:0,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/qchar.h:37,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/qstring.h:41,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/QString:1,
                 from /src/wmathtest/LaTeXText.h:4,
                 from /src/wmathtest/Exercise.h:4,
                 from /src/wmathtest/Exercise.cpp:1:
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h: In instantiation of ‘uint qHash(const T&, uint) [with T = WMathTest::Tag; uint = unsigned int]’:
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:952:32:   required from ‘QHash<Key, T>::Node** QHash<Key, T>::findNode(const Key&, uint*) const [with Key = WMathTest::Tag; T = QHashDummyValue; QHash<Key, T>::Node = QHashNode<WMathTest::Tag, QHashDummyValue>; uint = unsigned int]’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:808:36:   required from ‘QHash<Key, T>::iterator QHash<Key, T>::insert(const Key&, const T&) [with Key = WMathTest::Tag; T = QHashDummyValue]’
/opt/Qt/5.5/gcc_64/include/QtCore/qset.h:188:94:   required from ‘QSet<T>::iterator QSet<T>::insert(const T&) [with T = WMathTest::Tag]’
/src/wmathtest/Exercise.cpp:22:22:   required from here
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:103:5: error: no matching function for call to ‘qHash(const WMathTest::Tag&)’
     Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
     ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:103:5: note: candidates are:
In file included from /opt/Qt/5.5/gcc_64/include/QtCore/qset.h:37:0,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/QSet:1,
                 from /src/wmathtest/Tag.h:5,
                 from /src/wmathtest/Exercise.h:5,
                 from /src/wmathtest/Exercise.cpp:1:
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:65:52: note: constexpr uint qHash(char, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:65:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘char’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:66:52: note: constexpr uint qHash(uchar, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uchar key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:66:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘uchar {aka unsigned char}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:67:52: note: constexpr uint qHash(signed char, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(signed char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:67:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘signed char’
In file included from /opt/Qt/5.5/gcc_64/include/QtCore/qset.h:37:0,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/QSet:1,
                 from /src/wmathtest/Tag.h:5,
                 from /src/wmathtest/Exercise.h:5,
                 from /src/wmathtest/Exercise.cpp:1:
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:68:52: note: constexpr uint qHash(ushort, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ushort key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:68:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘ushort {aka short unsigned int}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:69:52: note: constexpr uint qHash(short int, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(short key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:69:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘short int’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:70:52: note: constexpr uint qHash(uint, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uint key, uint seed = 0) Q_DECL_NOTHROW { return key ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:70:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘uint {aka unsigned int}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:71:52: note: constexpr uint qHash(int, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(int key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:71:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘int’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:72:52: note: constexpr uint qHash(ulong, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ulong key, uint seed = 0) Q_DECL_NOTHROW
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:72:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘ulong {aka long unsigned int}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:78:52: note: constexpr uint qHash(long int, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(long key, uint seed = 0) Q_DECL_NOTHROW { return qHash(ulong(key), seed); }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:78:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘long int’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:79:52: note: constexpr uint qHash(quint64, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(quint64 key, uint seed = 0) Q_DECL_NOTHROW
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:79:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘quint64 {aka long long unsigned int}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:83:52: note: constexpr uint qHash(qint64, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(qint64 key, uint seed = 0) Q_DECL_NOTHROW { return qHash(quint64(key), seed); }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:83:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘qint64 {aka long long int}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:84:42: note: uint qHash(float, uint)
 Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(float key, uint seed = 0) Q_DECL_NOTHROW;
                                          ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:84:42: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘float’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:85:42: note: uint qHash(double, uint)
 Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(double key, uint seed = 0) Q_DECL_NOTHROW;
                                          ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:85:42: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘double’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:87:42: note: uint qHash(long double, uint)
 Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(long double key, uint seed = 0) Q_DECL_NOTHROW;
                                          ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:87:42: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘long double’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:89:52: note: constexpr uint qHash(QChar, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(const QChar key, uint seed = 0) Q_DECL_NOTHROW { return qHash(key.unicode(), seed); }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:89:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘QChar’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:90:41: note: uint qHash(const QByteArray&, uint)
 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QByteArray &key, uint seed = 0) Q_DECL_NOTHROW;
                                         ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:90:41: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘const QByteArray&’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:91:41: note: uint qHash(const QString&, uint)
 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QString &key, uint seed = 0) Q_DECL_NOTHROW;
                                         ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:91:41: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘const QString&’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:92:41: note: uint qHash(const QStringRef&, uint)
 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QStringRef &key, uint seed = 0) Q_DECL_NOTHROW;
                                         ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:92:41: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘const QStringRef&’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:93:41: note: uint qHash(const QBitArray&, uint)
 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QBitArray &key, uint seed = 0) Q_DECL_NOTHROW;
                                         ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:93:41: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘const QBitArray&’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:94:41: note: uint qHash(QLatin1String, uint)
 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW;
                                         ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:94:41: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘QLatin1String’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:98:32: note: template<class T> uint qHash(const T*, uint)
 template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW
                                ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:98:32: note:   template argument deduction/substitution failed:
In file included from /opt/Qt/5.5/gcc_64/include/QtCore/qglobal.h:74:0,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/qchar.h:37,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/qstring.h:41,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/QString:1,
                 from /src/wmathtest/LaTeXText.h:4,
                 from /src/wmathtest/Exercise.h:4,
                 from /src/wmathtest/Exercise.cpp:1:
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:103:5: note:   mismatched types ‘const T*’ and ‘WMathTest::Tag’
     Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
     ^
src/wmathtest/CMakeFiles/wmathtest.dir/build.make:146: recipe for target 'src/wmathtest/CMakeFiles/wmathtest.dir/Exercise.cpp.o' failed
make[2]: *** [src/wmathtest/CMakeFiles/wmathtest.dir/Exercise.cpp.o] Error 1
CMakeFiles/Makefile2:160: recipe for target 'src/wmathtest/CMakeFiles/wmathtest.dir/all' failed
make[1]: *** [src/wmathtest/CMakeFiles/wmathtest.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
    Exercise.cpp.o
In file included from /opt/Qt/5.5/gcc_64/include/QtCore/qglobal.h:74:0,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/qchar.h:37,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/qstring.h:41,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/QString:1,
                 from /wmathtest/LaTeXText.h:4,
                 from /src/wmathtest/Exercise.h:4,
                 from /wmathtest/Exercise.cpp:1:
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h: In instantiation of ‘uint qHash(const T&, uint) [with T = WMathTest::Tag; uint = unsigned int]’:
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:952:32:   required from ‘QHash<Key, T>::Node** QHash<Key, T>::findNode(const Key&, uint*) const [with Key = WMathTest::Tag; T = QHashDummyValue; QHash<Key, T>::Node = QHashNode<WMathTest::Tag, QHashDummyValue>; uint = unsigned int]’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:808:36:   required from ‘QHash<Key, T>::iterator QHash<Key, T>::insert(const Key&, const T&) [with Key = WMathTest::Tag; T = QHashDummyValue]’
/opt/Qt/5.5/gcc_64/include/QtCore/qset.h:188:94:   required from ‘QSet<T>::iterator QSet<T>::insert(const T&) [with T = WMathTest::Tag]’
/wmathtest/Exercise.cpp:22:22:   required from here
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:103:5: error: no matching function for call to ‘qHash(const WMathTest::Tag&)’
     Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
     ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:103:5: note: candidates are:
In file included from /opt/Qt/5.5/gcc_64/include/QtCore/qset.h:37:0,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/QSet:1,
                 from /wmathtest/Tag.h:5,
                 from /wmathtest/Exercise.h:5,
                 from /wmathtest/Exercise.cpp:1:
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:65:52: note: constexpr uint qHash(char, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:65:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘char’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:66:52: note: constexpr uint qHash(uchar, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uchar key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:66:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘uchar {aka unsigned char}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:67:52: note: constexpr uint qHash(signed char, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(signed char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:67:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘signed char’
In file included from /opt/Qt/5.5/gcc_64/include/QtCore/qset.h:37:0,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/QSet:1,
                 from /home/daniele/projects/wmathtestgenerator/src/wmathtest/Tag.h:5,
                 from /Exercise.h:5,
                 from /wmathtest/Exercise.cpp:1:
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:68:52: note: constexpr uint qHash(ushort, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ushort key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:68:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘ushort {aka short unsigned int}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:69:52: note: constexpr uint qHash(short int, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(short key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:69:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘short int’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:70:52: note: constexpr uint qHash(uint, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uint key, uint seed = 0) Q_DECL_NOTHROW { return key ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:70:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘uint {aka unsigned int}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:71:52: note: constexpr uint qHash(int, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(int key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:71:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘int’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:72:52: note: constexpr uint qHash(ulong, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ulong key, uint seed = 0) Q_DECL_NOTHROW
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:72:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘ulong {aka long unsigned int}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:78:52: note: constexpr uint qHash(long int, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(long key, uint seed = 0) Q_DECL_NOTHROW { return qHash(ulong(key), seed); }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:78:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘long int’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:79:52: note: constexpr uint qHash(quint64, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(quint64 key, uint seed = 0) Q_DECL_NOTHROW
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:79:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘quint64 {aka long long unsigned int}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:83:52: note: constexpr uint qHash(qint64, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(qint64 key, uint seed = 0) Q_DECL_NOTHROW { return qHash(quint64(key), seed); }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:83:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘qint64 {aka long long int}’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:84:42: note: uint qHash(float, uint)
 Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(float key, uint seed = 0) Q_DECL_NOTHROW;
                                          ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:84:42: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘float’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:85:42: note: uint qHash(double, uint)
 Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(double key, uint seed = 0) Q_DECL_NOTHROW;
                                          ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:85:42: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘double’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:87:42: note: uint qHash(long double, uint)
 Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(long double key, uint seed = 0) Q_DECL_NOTHROW;
                                          ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:87:42: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘long double’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:89:52: note: constexpr uint qHash(QChar, uint)
 Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(const QChar key, uint seed = 0) Q_DECL_NOTHROW { return qHash(key.unicode(), seed); }
                                                    ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:89:52: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘QChar’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:90:41: note: uint qHash(const QByteArray&, uint)
 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QByteArray &key, uint seed = 0) Q_DECL_NOTHROW;
                                         ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:90:41: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘const QByteArray&’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:91:41: note: uint qHash(const QString&, uint)
 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QString &key, uint seed = 0) Q_DECL_NOTHROW;
                                         ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:91:41: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘const QString&’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:92:41: note: uint qHash(const QStringRef&, uint)
 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QStringRef &key, uint seed = 0) Q_DECL_NOTHROW;
                                         ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:92:41: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘const QStringRef&’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:93:41: note: uint qHash(const QBitArray&, uint)
 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QBitArray &key, uint seed = 0) Q_DECL_NOTHROW;
                                         ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:93:41: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘const QBitArray&’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:94:41: note: uint qHash(QLatin1String, uint)
 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW;
                                         ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:94:41: note:   no known conversion for argument 1 from ‘const WMathTest::Tag’ to ‘QLatin1String’
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:98:32: note: template<class T> uint qHash(const T*, uint)
 template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW
                                ^
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:98:32: note:   template argument deduction/substitution failed:
In file included from /opt/Qt/5.5/gcc_64/include/QtCore/qglobal.h:74:0,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/qchar.h:37,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/qstring.h:41,
                 from /opt/Qt/5.5/gcc_64/include/QtCore/QString:1,
                 from /home/daniele/projects/wmathtestgenerator/src/wmathtest/LaTeXText.h:4,
                 from /home/daniele/projects/wmathtestgenerator/src/wmathtest/Exercise.h:4,
                 from /thtest/Exercise.cpp:1:
/opt/Qt/5.5/gcc_64/include/QtCore/qhash.h:103:5: note:   mismatched types ‘const T*’ and ‘WMathTest::Tag’
     Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
     ^
src/wmathtest/CMakeFiles/wmathtest.dir/build.make:146: recipe for target 'src/wmathtest/CMakeFiles/wmathtest.dir/Exercise.cpp.o' failed
make[2]: *** [src/wmathtest/CMakeFiles/wmathtest.dir/Exercise.cpp.o] Error 1
CMakeFiles/Makefile2:160: recipe for target 'src/wmathtest/CMakeFiles/wmathtest.dir/all' failed
make[1]: *** [src/wmathtest/CMakeFiles/wmathtest.dir/all] Error 2
Makefile:76: recipe for target 'all' failed

I've created the class, the operator== and the qHash for the class. Then I've created a typedef for the class but this does not work.

What I'm doing wrong?

Tag.h

#ifndef WMATHTEST_TAG_H_
#define WMATHTEST_TAG_H_

#include <QString>
#include <QSet>

namespace WMathTest {

class Tag {

public:

    Tag() = default;
    Tag(const QString &text);
    Tag(const Tag &tag) = default;
    virtual ~Tag() = default;
    void setText(const QString &text);
    const QString& getText() const;
    bool operator==(const Tag &other);

private:

QString m_text;
};

} // namespace WMathTest


inline uint qHash(const WMathTest::Tag &tag, uint seed) {
    return qHash(tag.getText(), seed);
}

typedef QSet<WMathTest::Tag> TagList;

#endif // !WMATHTEST_TAG_H_

Tag.cpp

#include "wmathtest/Tag.h"

namespace WMathTest {

///////////////////////////////////////////////////////////////////////////////
// PUBLIC SECTION                                                            //
///////////////////////////////////////////////////////////////////////////////

Tag::Tag(const QString &text) :
    m_text(text) {

}

void Tag::setText(const QString &text) {
    m_text = text;
}

const QString& Tag::getText() const {
    return m_text;
}

bool Tag::operator==(const Tag &other) {
    return m_text == other.m_text;
}

} // namespace WMathTest

Exercise.h

#ifndef WMATHTEST_EXERCISE_H_
#define WMATHTEST_EXERCISE_H_

#include "wmathtest/LaTeXText.h"
#include "wmathtest/Tag.h"
#include <QString>

namespace WMathTest {

class Exercise {

public:

    Exercise() = default;
    virtual ~Exercise() = default;
    void setID(const QString &id);
    void setProblem(const LaTeXText &problem);
    void setSolution(const LaTeXText &solution);
    void addArgumentTag(const Tag &tag);
    void addArgumentTag(const QString &tag);
    QString getID() const;
    LaTeXText getProblem() const;
    LaTeXText getSolution() const;
    const TagList& getArgumentTagList() const;

private:

    QString m_id;
    LaTeXText m_problem;
    LaTeXText m_solution;
    TagList m_tagList;
};

} // namespace WMathTest

#endif // !WMATHTEST_EXERCISE_H_

Exercise.cpp

#include "wmathtest/Exercise.h"

namespace WMathTest {

///////////////////////////////////////////////////////////////////////////////
// PUBLIC SECTION                                                            //
///////////////////////////////////////////////////////////////////////////////

void Exercise::setID(const QString &id) {
    m_id = id;
}

void Exercise::setProblem(const LaTeXText &problem) {
    m_problem = problem;
}

void Exercise::setSolution(const LaTeXText &solution) {
    m_solution = solution;
}

void Exercise::addArgumentTag(const Tag &tag) {
    m_tagList.insert(tag);
}

void Exercise::addArgumentTag(const QString &tag) {
    m_tagList.insert(Tag(tag));
}

QString Exercise::getID() const {
    return m_id;
}

LaTeXText Exercise::getProblem() const {
    return m_problem;
}

LaTeXText Exercise::getSolution() const {
    return m_solution;
}

const TagList& Exercise::getArgumentTagList() const {
    return m_tagList;
}

} // namespace WMathTest

Solution

  • A hash is an unary function (one argument only) and it is a function in mathematical sense (returns same value for specific argument and will return valid value for complete set of arguments).

    Hash function has one important condition which has to be always meet to be working properly: if two objects are considered as equal then hash values for this objects HAVE TO be also equal. So for example if you what case insensitive container where strings are the key, you have to provide case insensitive hash function.

    Please note that additional argument for qHash functions you are see in documentation: seed always has a default value! So this function can be called with single argument! This argument is just an option which gives you a chance to tweak hash function when you are building custom hash function for a complex type.

    Fix your code like this:

    inline uint qHash(const WMathTest::Tag &tag) {
        return qHash(tag.getText(), 0xa03f); // arbitrary value
    }
    

    or like this:

    inline uint qHash(const WMathTest::Tag &tag, uint seed = 0) {
        return qHash(tag.getText(), seed^0xa03f);
    }
    

    In case of more complex type hash function could look like this (example why seed can be useful):

    inline uint qHash(const DoubleStringValue &tag, uint seed = 0) {
        return qHash(tag.firstText(), seed^0xa03f)^qHash(tag.secondText(), seed^0x17a317a3);
    }
    

    Note that this way if there are two DoubleStringValue objects where firstText and secondText are flipped the hash value for both of them will be different.

    I recommend reading some documentation about how containers with hash functions work, and why they are faster than alternative solutions (for example red–black tree).