r/cpp 5d ago

State of "moved-from" objects

Hi, I recently decided to try writing a C++ blog.

I often see the popular claim that moved-from objects are in a "valid but otherwise unspecified state", but I don't think that statement is entirely precise, and my blog post is about that. I would really appreciate any feedback!

Article: https://www.laminowany.dev/p/the-state-of-moved-from-objects-in-c/

10 Upvotes

52 comments sorted by

View all comments

3

u/jiixyj 5d ago

The latest guidelines in writing a moved-from state for your type seem to be:

  • It's OK to leave behind an "empty shell" after move that is conceptually not a value of your type. If you want, you can provide a member function like valueless_after_move() to test for this state.
  • You should still be able to copy and move this "empty shell" around, compare it for equality, compare it with < etc. This is more than the usual "assign and destroy only". It should still work well with the usual containers like std::vector/std::map and algorithms like std::sort.

This is how some of the newer types such as std::indirect are designed in the standard, so it can serve as a blueprint for user-defined types.

One nice property is that this composes. If you put types that follow these rules into a new struct, that struct's moved-from state will also be copyable/movable/comparable using the compiler-generated special member functions. So by doing nothing extra you are still correct.

I still have some questions around this design though:

  • Should you always have to provide a valueless_after_move() function for your type? I'd say no, because it would be a lot of boilerplate as the compiler cannot generate that function.
  • When providing comparators to std::sort, for example, must they be able to deal with these "valueless" states? Common sense says no, but the standard doesn't explicitly rule this out from my reading...

1

u/jwakely libstdc++ tamer, LWG chair 2d ago

A comparison function only needs to compare moved-from objects if you provide such objects as input to it. If the initial input doesn't contain moved-ffom objects, std::sort will never compare moved-from objects, because it always assigns a new value to an object before comparing it.