Details
-
Bug
-
Resolution: Done
-
P3: Somewhat important
-
4.8.4, 5.1.1
-
None
-
Ubuntu 12.04
Description
The attached code snippet can be used to reproduce the issue:
#include <QCoreApplication> #include <QHash> #include <QDebug> // uncomment to see the compile error #define USE_FOO_NAMESPACE #ifdef USE_FOO_NAMESPACE #define NS foo:: namespace foo { #else #define NS #endif class Foo { public: Foo(int id) : m_id(id) {} int id() const { return m_id; } private: int m_id; }; #ifdef USE_FOO_NAMESPACE } #endif unsigned int qHash(const NS Foo& foo) { return foo.id(); } bool operator ==(const NS Foo &left, const NS Foo &right) { return (left.id() == right.id()); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); NS Foo firstFoo(1); NS Foo secondFoo(2); QHash<NS Foo, int> fooHash; fooHash.insert(firstFoo, 1); fooHash.insert(secondFoo, 2); qDebug() << fooHash.count(); }
This produces a compiler error:
g++ -c -pipe -g -Wall -W -D_REENTRANT -fPIE -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/mkspecs/linux-g++ -I. -I. -I../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include -I../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtWidgets -I../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtGui -I../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore -I. -o main.o main.cpp In file included from ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/qhash.h:1:0, from ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/QHash:1, from main.cpp:2: ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h: In function ‘uint qHash(const T&, uint) [with T = foo::Foo, uint = unsigned int]’: ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:890:9: instantiated from ‘QHash<Key, T>::Node** QHash<Key, T>::findNode(const Key&, uint*) const [with Key = foo::Foo, T = int, QHash<Key, T>::Node = QHashNode<foo::Foo, int>, uint = unsigned int]’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:764:36: instantiated from ‘QHash<Key, T>::iterator QHash<Key, T>::insert(const Key&, const T&) [with Key = foo::Foo, T = int]’ main.cpp:51:27: instantiated from here ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:111:26: error: no matching function for call to ‘qHash(const foo::Foo&)’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:111:26: note: candidates are: ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:63:13: note: uint qHash(char, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:63:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘char’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:64:13: note: uint qHash(uchar, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:64:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘uchar {aka unsigned char}’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:65:13: note: uint qHash(signed char, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:65:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘signed char’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:66:13: note: uint qHash(ushort, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:66:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘ushort {aka short unsigned int}’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:67:13: note: uint qHash(short int, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:67:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘short int’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:68:13: note: uint qHash(uint, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:68:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘uint {aka unsigned int}’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:69:13: note: uint qHash(int, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:69:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘int’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:70:13: note: uint qHash(ulong, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:70:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘ulong {aka long unsigned int}’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:78:13: note: uint qHash(long int, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:78:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘long int’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:79:13: note: uint qHash(quint64, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:79:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘quint64 {aka long long unsigned int}’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:87:13: note: uint qHash(qint64, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:87:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘qint64 {aka long long int}’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:88:13: note: uint qHash(QChar, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:88:13: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘QChar’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:89:20: note: uint qHash(const QByteArray&, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:89:20: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘const QByteArray&’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:90:20: note: uint qHash(const QString&, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:90:20: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘const QString&’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:91:20: note: uint qHash(const QStringRef&, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:91:20: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘const QStringRef&’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:92:20: note: uint qHash(const QBitArray&, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:92:20: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘const QBitArray&’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:93:20: note: uint qHash(QLatin1String, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:93:20: note: no known conversion for argument 1 from ‘const foo::Foo’ to ‘QLatin1String’ ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:101:32: note: template<class T> uint qHash(const T*, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:109:34: note: template<class T> uint qHash(const T&, uint) ../../../Qt/qt-everywhere-enterprise-src-5.1.1/qtbase/include/QtCore/../../src/corelib/tools/qhash.h:111:29: warning: control reaches end of non-void function [-Wreturn-type] make: *** [main.o] Error 1
If the
unsigned int qHash(const NS Foo& foo) and
bool operator ==(const NS Foo &left, const NS Foo &right)
it works if those are put inside the namespace too. This is something which should at least be documented to QHash documentation.
Attachments
For Gerrit Dashboard: QTBUG-34912 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
90411,2 | Document that qHash(T) must be in T's namespace, due to ADL | dev | qt/qtbase | Status: MERGED | +2 | 0 |