id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 9916,Allocator propagation incorrect in the assignment operator of most containers,Ion Gaztañaga,Ion Gaztañaga,"When copy or move assigning containers, the allocator is propagated according to propagate_on_container_copy|move_assignment only if both allocators compare equal. This is incorrect as allocators must be propagated independently from allocator comparison. For move construct correct logic would be, according to H. Hinnant's answer in StackOverflow (http://stackoverflow.com/a/12334918): ----- C& operator=(C&& c) If alloc_traits::propagate_on_container_move_assignment::value is true, dumps resources, move assigns allocators, and transfers resources from c. If alloc_traits::propagate_on_container_move_assignment::value is false and get_allocator() == c.get_allocator, dumps resources, and transfers resources from c. If alloc_traits::propagate_on_container_move_assignment::value is false and get_allocator() != c.get_allocator, move assigns each c[i]. Notes: When alloc_traits::propagate_on_container_move_assignment::value is true the move assignment operator can be specified noexcept because all it is going to is deallocate current resources and then pilfer resources from the source. Also in this case, the allocator must also be move assigned, and that move assignment must be noexcept for the container's move assignment to be noexcept. When alloc_traits::propagate_on_container_move_assignment::value is false, and if the two allocators are equal, then it is going to do the same thing as #1. However one doesn't know if the allocators are equal until run time, so you can't base noexcept on this possibility. When alloc_traits::propagate_on_container_move_assignment::value is false, and if the two allocators are not equal, then one has to move assign each individual element. This may involve adding capacity or nodes to the target, and thus is intrinsically noexcept(false). ----- For copy assignment the steps would be: If alloc_traits::propagate_on_container_move_assignment::value is true, and get_allocator() != c.get_allocator dumps resources, copy assigns allocators, and assigns from [c.begin(), c.end()) If alloc_traits::propagate_on_container_move_assignment::value is true and get_allocator() == c.get_allocator, copy assigns allocators, and assigns from [c.begin(), c.end()) If alloc_traits::propagate_on_container_move_assignment::value is false assigns from [c.begin(), c.end()) ",Bugs,closed,Boost 1.56.0,container,Boost 1.55.0,Problem,fixed,,