std::vector allocator-extended move constructor

Jonathan Wakely jwakely.gcc@gmail.com
Fri Nov 15 12:17:00 GMT 2013


On 15 November 2013 12:11, Jonathan Wakely wrote:
> I'm finishing allocator support for <map> and <set> and noticed a
> problem in std::vector:
>
>   /// Move constructor with alternative allocator
>   vector(vector&& __rv, const allocator_type& __m)
>   : _Base(std::move(__rv), __m)
>   {
>     if (__rv.get_allocator() != __m)
>       {
>         this->_M_impl._M_finish =
>           std::__uninitialized_move_a(__rv.begin(), __rv.end(),
>                       this->_M_impl._M_start,
>                       _M_get_Tp_allocator());
>         __rv.clear();
>       }
>   }
>
> The good news is that if all instances of the allocator type compare
> equal then the _Base will just move some pointers, so we can have a
> conditional noexcept:
>       noexcept(_Alloc_traits::_S_always_equal())
>
> The bad news is that it's not currently exception-safe.  I should have
> used __uninitialized_copy_a there.  If moving any element throws an
> exception then we leak any already-moved elements.

Correction, we don't leak, as __uninitialized_copy_a will destroy
them, but we do modify the __rv object, so we don't have the strong
guarantee.  I'm not sure if that constructor is supposed to provide
the strong guarantee or not.



More information about the Libstdc++ mailing list