It may be compiling now because of the signature change, but the example you posted actually does nothing to change the map or the Foo instance with the key 1.
m.value(1) returns a new instance of Foo if there is nothing in the map with key 1, otherwise it returns a copy of the Foo instance stored at key 1. The map itself is not changed; that is if there is no key 1 in the map, nothing is added.
Likewise, because the Foo instance is a copy, the call to Foo :: setX() changes only the value of the temporary returned by m.value(). Once that temporary goes out of scope, it disappears.
The only ways I see to modify the QMap or a value in it are QMap::insert(), QMap::take(), or the non-const version of QMap::operator[]().
So you would have to rewrite your example code like this:
int main() {
QMap<int, Foo> m;
Foo tmp = m.value(1);
tmp.setX(1);
m[1] = tmp; // Up until this point, the map is empty. This statement adds the first key, value pair to it
}
int main() {
QMap<int, Foo> m;
Foo tmp = m.value(1);
tmp.setX(1);
m[1] = tmp; // Up until this point, the map is empty. This statement adds the first key, value pair to it
}
To copy to clipboard, switch view to plain text mode
But this code could be simplified to this (and be more clear as to what is actually going on):
int main() {
QMap<int, Foo> m;
Foo tmp;
tmp.setX(1);
m[1] = tmp; // Up until this point, the map is empty. This statement adds the first key, value pair to it
}
int main() {
QMap<int, Foo> m;
Foo tmp;
tmp.setX(1);
m[1] = tmp; // Up until this point, the map is empty. This statement adds the first key, value pair to it
}
To copy to clipboard, switch view to plain text mode
I don't know why the signature change between Qt5 and Qt6. I think you are correct that the Qt5 const T version was to make it clear that QMap::value() returns a copy and not a reference, so code like you posted would not compile. I think the Qt6 non-const version is probably a bad idea because it does allow your code to compile, but it introduces a bug. Returning a non-const reference would probably also be a bad idea because it could introduce bugs due to simply retrieving something from the map, using it, and inadvertently assigning a new value without realizing it was also modifying the stored value.
The std::map<> counterpart operator[] returns a non-const reference to T and modifies the map by inserting a default value of T if the key is not found. I've been burned by that before.
Bookmarks