According to current Standard (20.7.9), std::allocator
has a member propagate_on_container_move_assignment
which is set to true_type
:
template class allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template struct rebind { typedef allocator other; };
typedef true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
[...]
std::allocator
has no data members and always compared as equal with any other std::allocator
. Is there any reason to move those default allocators on move assignment?
I'm answering relative to C++11, as you indicated in the tag:
If the trait weren't true, then assignment operations would need to perform a runtime check on whether the allocators are equal. Yes, of course the allocators would always be equal, but the code doesn't know that and would still have to perform the check, and thus you cannot offer a noexcept guarantee. With POCMA = true, you can statically know that you will steal resources and thus won't throw.
C++14 made the std::allocator
have POCMA = true (in LWG2103). It was false in C++11.
C++17 introduced the new trait is_always_equal
(in N4258) to allow a non-throwing exception specification for operations even when POCMA is false.
(I think it's fair to say that the design of allocators has never quite been completed, and to this day nobody is entirely sure how they are supposed to work.)