[SOLVED] Can't modify a QSet element
I get the error on trying to access the iterator reference:
QSet<UniqueWord>::iterator iter = uniqueWords.find(word);
iter->addOccurrence(position); // this gets an error@
bq. error: C2662: 'UniqueWord::addOccurrence' : cannot convert 'this' pointer from 'const UniqueWord' to 'UniqueWord &'
Conversion loses qualifiers
What does the "this" pointer has to do with anything? What am I missing?
Solved, making addOccurrence() const and the non-hashing members of UniqueWord mutable fixed it.
I feel like this issue deserves noting in the documentation... I lost like 20 minutes trying to figure it out and the compiler error was anything but useful.
So, in short - QSet implies that the value it contains cannot be changed in any way because of an assumption that it will change the hashing result for the item. In my case I only used a QString member to calculate the hash, while addOccurrence() appends to a QList that is in no way considered by the hash. And since you are not supposed to modify a QSet value in order to not disturb the hash, only const methods are allowed. And QList doesn't have any const methods that append, since appending obviously changes something. Making addOccurrence() const and marking the QList as mutable to exclude it from tracking the const correctness solved the error.
So the docs should include something like:
QSet uses const correctness to prevent values from being modified and render their hash results invalid. You can only change QSet value members that are not being used to calculate the hash value. Any method that changes such a value must be const to satisfy the const correctness chain, and the modified member should be marked as mutable, so as to be ignored from const correctness checking.
I added a doc note... but how the hell scrolls all the way down :)