Initialize a QHash
-
Hi,
this might be a noob question and I am not sure if it's rather about how QHash's initializer lists work / don't work or perhaps just about the basic c++ means of list initialization.Note test0 = Note("f","#",4); QHash<QVector<int>, QVector<int>> test1{ {QVector<int>{1,2,3}, QVector<int>{1,2,3} } }; QHash<Note, QVector<int>> test3; QHash<Note, QVector<int>> test4{ {Note("f","#",4), QVector<int>{1,2,3} } };
The first three variables are initialized without problems. But "test4" gives a mess of build errors, the most sensible being:
C:/Qt/5.15.0/mingw81_64/include/QtCore/qhashfunctions.h:118:28: error: no matching function for call to 'qHash(const Note&)' noexcept(noexcept(qHash(t)))
I don't understand this error message.
The non-default constructor of the class Note isNote::Note(QString name, QString accidental, int midiOctave, Note::Duration duration, bool dotted) { m_name = name; m_accidental = accidental; m_midiOctave = midiOctave; m_duration = duration; m_dotted = dotted; }
Is what I try to achieve possible? Can I change the Constructor or write an additional one for this purpose?
-
@SeDi said in Initialize a QHash:
no matching function for call to 'qHash(const Note&)'
Isn't this obvious enough? It's also in the docs: The key type of a QHash must provide operator==() and a global hash function called qHash().
-
Unfortunately I still can't get it to work. I have defined an:
inline bool operator==(const Note &n2) const { return n2.midiNumber() == this->midiNumber(); }
This compiles well, at least as long as I comment out:
//QHash<Note, QVector<int>> test4{ {Note("f","#",4), QVector<int>{1,2,3} } };
I have tried dozens of versions and places for my:
uint qHash(const Note& key, uint seed = 0) { Q_UNUSED(seed) return uint(key.midiNumber()); }
It is now located in Note.h right after the end of the class definition. Shortened declaration:
#ifndef NOTE_H #define NOTE_H #include <QHash> class Note { public: explicit Note(); Note(QString name, QString accidental, int midiOctave, Note::Duration duration = Note::Duration::WHOLE, bool dotted = false); int midiNumber() const; inline bool operator==(const Note &n2) const { return n2.midiNumber() == this->midiNumber(); } private: QString m_name = "c"; QString m_accidental = ""; int m_midiOctave = 5; }; /// after class definition has ended: uint qHash(const Note& key, uint seed = 0) { Q_UNUSED(seed) return uint(key.midiNumber()); } #endif // NOTE_H
I get this build error log (test4 still commented out):
debug/main.o: In function `qHash(Note const&, unsigned int)': C:\Users\SeDi\cpp\build-BrassTutor-Desktop_Qt_5_15_0_MinGW_64_bit-Debug/../BrassTutor/note.h:71: multiple definition of `qHash(Note const&, unsigned int)' debug/controller.o:C:\Users\SeDi\cpp\build-BrassTutor-Desktop_Qt_5_15_0_MinGW_64_bit-Debug/../BrassTutor/note.h:71: first defined here debug/note.o: In function `std::operator&(std::memory_order, std::__memory_order_modifier)': C:\Users\SeDi\cpp\build-BrassTutor-Desktop_Qt_5_15_0_MinGW_64_bit-Debug/../BrassTutor/note.h:71: multiple definition of `qHash(Note const&, unsigned int)' debug/controller.o:C:\Users\SeDi\cpp\build-BrassTutor-Desktop_Qt_5_15_0_MinGW_64_bit-Debug/../BrassTutor/note.h:71: first defined here debug/task.o: In function `operator new(unsigned long long, void*)': C:\Users\SeDi\cpp\build-BrassTutor-Desktop_Qt_5_15_0_MinGW_64_bit-Debug/../BrassTutor/note.h:71: multiple definition of `qHash(Note const&, unsigned int)' debug/controller.o:C:\Users\SeDi\cpp\build-BrassTutor-Desktop_Qt_5_15_0_MinGW_64_bit-Debug/../BrassTutor/note.h:71: first defined here debug/moc_controller.o: In function `QHash<int, QHashDummyValue>::concrete(QHashData::Node*)': C:\Users\SeDi\cpp\build-BrassTutor-Desktop_Qt_5_15_0_MinGW_64_bit-Debug/debug/../../BrassTutor/note.h:71: multiple definition of `qHash(Note const&, unsigned int)' debug/controller.o:C:\Users\SeDi\cpp\build-BrassTutor-Desktop_Qt_5_15_0_MinGW_64_bit-Debug/../BrassTutor/note.h:71: first defined here debug/moc_task.o: In function `QMetaObject const* QMetaObject::staticMetaObject<QObject::staticMetaObject>()': C:\Users\SeDi\cpp\build-BrassTutor-Desktop_Qt_5_15_0_MinGW_64_bit-Debug/debug/../../BrassTutor/note.h:71: multiple definition of `qHash(Note const&, unsigned int)' debug/controller.o:C:\Users\SeDi\cpp\build-BrassTutor-Desktop_Qt_5_15_0_MinGW_64_bit-Debug/../BrassTutor/note.h:71: first defined here collect2.exe: error: ld returned 1 exit status mingw32-make[1]: *** [Makefile.Debug:90: debug/BrassTutor.exe] Error 1 mingw32-make: *** [Makefile:45: debug] Error 2
I don't understand how this can be possible. I am 100% sure that I don't have a second definition of qHash() anywhere in my code and the header file is guarded with #ifndef against multiple includes.
There is probably a very basic thing that I totally don't see or understand. -
After days of searching I've found it myself right after posting this. Sorry.
Following this article I re-applied "inline" and now it works.
Thanks!
For posterity:#ifndef NOTE_H #define NOTE_H #include <QHash> class Note { ///... inline bool operator==(const Note &n2) const { return n2.midiNumber() == this->midiNumber(); } ///... }; /// after class definition has ended: inline uint qHash(const Note& key, uint seed = 0) { Q_UNUSED(seed) return uint(key.midiNumber()); } #endif // NOTE_H