
Howard Hinnant wrote:
[snip]
There is nothing in the rvalue ref proposals that really nails this down. It is up to each class to define its behavior after a move. At the very least it should support assignment and destruction in order to work with generic code. Beyond that I'd say the class should be free to implement whatever semantics / interface it feels best.
I respectfully disagree ;-) If the object is still there and can be used it should be usable. If we had destructive move-semantics, I would agree that the state of the objects should be undefined (or even better, destroyed), but in that case I would expect compiler help to detect uses of move-destructed variables after the move-destruction. std::vector<T> myvect(...); //myvect's destructor is called, the object is not longer usable std::vector<T> myvect2(std::destructive_move(myvect)); myvect.resize(1000); <-- COMPILATION ERROR In my opinion, the standard should clearly say what happens with an standard component. An example: what's the state of an STL container after being moved? std::vector<T> myvect(...); std::vector<T> myvect2(std::move(myvect)); myvect.resize(1000); <-- is this correct? If myvect is allowed to be in a non-usable state, the allocator might be moved from myvect to myvect2. If myvect should be usable, the allocator should be copied --> corollary: If we want non-throwing move constructors and assignments (which is surely required for objects we want to place in STL containers, like std::list<std::vector<T> >) allocator copying shouldn't throw. If the standard does not specify anything, implementors of allocators must always support the worst case (copying shouldn't throw) but they can't use the advantages (the vector is NOT reusable). Users also get the worst of both worlds. Since current move semantics are non-destructive the state of the object should be usable. For objects that have a default-constructor (like shared_ptr or vector) the moved state could be equal to default-constructed (which is consistent *and* usable). And no-throw guarantee should be required for such move operations This might complicate a bit the implementation of allocators, but it's perfectly possible to achieve this with containers. For shared_ptr, I don't know if the state should be default-constructed, but I would like to reuse that object via reset(). For objects that have no such default-state, and have no resource reassignment functions (like reset() or similar) there is no problem because there is no interface to reuse the object. For objects that don't have default-constructor but have resource reassignment functions, the state might be undefined, but I would require object reuse capability. In any case, you need to internally maintain the "moved" state so that the destructor does not crash the program. Since we have to pay some price (the zombie state, if you want to call it), let's take something in return. My 2 cents, Ion