Boost C++ Libraries: Ticket #9916: Allocator propagation incorrect in the assignment operator of most containers https://svn.boost.org/trac10/ticket/9916 <p> When copy or move assigning containers, the allocator is propagated according to propagate_on_container_copy|move_assignment only if both allocators compare equal. </p> <p> This is incorrect as allocators must be propagated independently from allocator comparison. </p> <p> For move construct correct logic would be, according to H. Hinnant's answer in <a class="missing wiki">StackOverflow</a> (<a class="ext-link" href="http://stackoverflow.com/a/12334918"><span class="icon">​</span>http://stackoverflow.com/a/12334918</a>): </p> <hr /> <p> C&amp; operator=(C&amp;&amp; c) </p> <blockquote> <p> If alloc_traits::propagate_on_container_move_assignment::value is true, dumps resources, move assigns allocators, and transfers resources from c. </p> </blockquote> <blockquote> <p> If alloc_traits::propagate_on_container_move_assignment::value is false and get_allocator() == c.get_allocator, dumps resources, and transfers resources from c. </p> </blockquote> <blockquote> <p> If alloc_traits::propagate_on_container_move_assignment::value is false and get_allocator() != c.get_allocator, move assigns each c[i]. </p> </blockquote> <p> Notes: </p> <blockquote> <p> 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. </p> </blockquote> <blockquote> <p> 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 <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/1" title="#1: Bugs: boost.build causes ftjam to segfault (closed: Wont Fix)">#1</a>. However one doesn't know if the allocators are equal until run time, so you can't base noexcept on this possibility. </p> </blockquote> <blockquote> <p> 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). </p> </blockquote> <hr /> <p> For copy assignment the steps would be: </p> <blockquote> <p> 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()) </p> </blockquote> <blockquote> <p> 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()) </p> </blockquote> <blockquote> <p> If alloc_traits::propagate_on_container_move_assignment::value is false assigns from [c.begin(), c.end()) </p> </blockquote> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9916 Trac 1.4.3 Ion Gaztañaga Mon, 21 Apr 2014 12:03:14 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/9916#comment:1 https://svn.boost.org/trac10/ticket/9916#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> In [develop 0b720f8]<br /> </p> <p> Fixed <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/9916" title="#9916: Bugs: Allocator propagation incorrect in the assignment operator of most ... (closed: fixed)">#9916</a>: "Allocator propagation incorrect in the assignment operator of most".<br /> </p> <p> Fixed <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/9932" title="#9932: Bugs: Missing assignment operator from related static_vector (closed: fixed)">#9932</a>: "Missing assignment operator from related static_vector".<br /> </p> <p> Added missing details from issue <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/9915" title="#9915: Bugs: Documentation issues regarding vector constructors and resize methods ... (closed: fixed)">#9915</a> </p> Ticket