Results 1 to 2 of 2

Thread: Constness of object returned by QMap::value in Qt5 vs Qt6

  1. #1
    Join Date
    Oct 2024
    Posts
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Constness of object returned by QMap::value in Qt5 vs Qt6

    I noticed that the code that doesn't compile with Qt5

    Qt Code:
    1. #include <QMap>
    2.  
    3. class Foo {
    4. public:
    5. void setX(int x) { _x = x; }
    6. private:
    7. int _x;
    8. };
    9.  
    10. int main() {
    11. QMap<int, Foo> m;
    12. m.value(1).setX(1);
    13. }
    To copy to clipboard, switch view to plain text mode 

    suddenly started to compile with Qt6. This is because of change in QMap::value signature from

    Qt Code:
    1. const T QMap::value(const Key &key, const T &defaultValue = T()) const
    To copy to clipboard, switch view to plain text mode 

    to

    Qt Code:
    1. T QMap::value(const Key &key, const T &defaultValue = T()) const
    To copy to clipboard, switch view to plain text mode 

    What is the rationale behind this change? As you can see, the Qt5 version prevented developers from making accidental mistakes, if they assumed that `T` is returned by reference.

    There are probably more changes like this, another method that I am aware of, with the same effect, is

    Qt Code:
    1. const T QMap::operator[](const Key &key) const
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,243
    Thanks
    303
    Thanked 866 Times in 853 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Constness of object returned by QMap::value in Qt5 vs Qt6

    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:

    Qt Code:
    1. int main() {
    2. QMap<int, Foo> m;
    3. Foo tmp = m.value(1);
    4. tmp.setX(1);
    5. m[1] = tmp; // Up until this point, the map is empty. This statement adds the first key, value pair to it
    6. }
    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):

    Qt Code:
    1. int main() {
    2. QMap<int, Foo> m;
    3. Foo tmp;
    4. tmp.setX(1);
    5. m[1] = tmp; // Up until this point, the map is empty. This statement adds the first key, value pair to it
    6. }
    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.
    Last edited by d_stranz; 3rd October 2024 at 20:16.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. TypeError: Object [object Object] has no method 'sendData'
    By TheIndependentAquarius in forum Qt Quick
    Replies: 2
    Last Post: 30th November 2013, 06:54
  2. Replies: 1
    Last Post: 4th January 2013, 19:32
  3. Replies: 1
    Last Post: 8th November 2011, 23:27
  4. how to receive a object returned by a method via QtDBus
    By stackpop in forum Qt Programming
    Replies: 0
    Last Post: 30th August 2011, 11:10
  5. How to Calculate the memory occupied by a QMap object
    By ahmedb in forum Qt Programming
    Replies: 5
    Last Post: 6th May 2010, 14:26

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.