c++qtmove-semantics

Is using QString after being `std::move`d defined?


Consider following pattern, stripped of details for simplicity:

 QString str  = /* expression */
 /* some actions with str */
 foo(std::move(str));

 str =  /* expression */
 /* some actions with str */
 foo(std::move(str));

Does reuse of str yield defined behaviour in Qt 4.8.6? Qt 5.x?


Solution

  • A move operation leaves the moved-from object in a "valid but unspecified state":

    16.5.5.16 Moved-from state of library types [lib.types.movedfrom]

    Objects of types defined in the C ++ standard library may be moved from. Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

    This statement, from the C++ standard, refers to the classes from the C++ library, as noted. However, it is a fairly easy bet that the Qt library seeks to comply to the same standards here, and this applies to the Qt library as well. It's a very safe bet to make (and it happens to be true, too).

    "Valid but unspecified" state means that the moved-from object is still a valid, well-formed object. Because it's unspecified you have no guarantees, whatsoever, that if you call its size() method that you'll get any particular value. It could be 0 (probably), or it could be something else. However, since it's a valid object, whatever you get from a size() of a moved-from QString, if you then proceed and check what's in the string, you'll see the same exact number of character in there.

    And, since it's a valid QString object you are free to completely replace its contents by assigning something to it, leaving the object is a fully-specified, valid state.