
Peter Dimov wrote:
Joe Gottman wrote:
There are many more ways to reuse an object than assignment and reset. For instance, I would be extremely disappointed if the following code didn't work:
vector<double> foo; vector<double> bar = move(foo); foo.resize(10); for (size_t n = 0; n < 10; ++n) { foo[n] = n + 7; }
The code will work under any implementation of the move constructor, IMO.
Well, some argue that only a move assignment or destructor should work after an object is being moved. I think the container should continue to work. I would be really disappointed if Joe's code does not work.
The more interesing question is, given: bar = move(foo);
would you be extremely disappointed if foo doesn't retain its allocator instance but gets bar's after the move?
If you want to left bar usable there is no other chance than swapping allocators. I would like to differentiate two cases with containers: Move assignment: It can easily implemented in terms of swap. Allocators are also swapped if they are not equal (or just swapped without any question). Allocators must go with the moved values. Move constructor: This is really tricky. If we want to left the moved object usable, we need to copy the allocator. Something like: Container(Container &&moved_container) : allocator_(moved_container_.allocator_) //Note, copy constructed { //Default initialization // .... //and now swap this->swap(moved_container); } Metrowerks/Freescale implementation implemented something like this, so moved containers were left perfectly usable. Since in Interprocess I wanted to maintain containers usable after being moved I've chosen the same option. The problem is that the allocator must be copy constructed and then swapped. This means that if we want a no-throw move constructor, allocator copying can't throw. In practice, I haven't seen an allocator (stateless or stateful= with a throwing copy-constructor, even shared memory ones. And if they need to acquire resources, they could delay the exception launch until the allocation function. The dynamic allocation of the "end" node in some containers (some implementation just embed them in the container so there is no problem) might also throw. But nothing that can't be delayed until an insertion is requested. The standard might easily mandate non-throwing copy constructors for allocators without breaking code and limiting current allocators. To sum up: Leaving the moved container fully usable and having no-throw guarantee for move constructors needs some tweaks, but in practice I think it's perfectly achievable and offers big advantages. Regards, Ion