For example, from std::deque::operator = in C++ Reference:
(1) Copy Assignment (const std::deque &other)
A POCCA (propagate-on-container-copy-assignment) allocator is copy-assigned as part of the container's copy assignment. Likewise, a POCMA allocator is move-assigned when the container's move assigned.
Does the quote above mean that I can't copy-assign the elements, so I have to destroy and deallocate ALL the elements first, using
this->get_allocator()
, and then allocate and construct the elements, usingother.get_allocator()
?
Correct.
But if that is the case, why should I use
other.get_allocator
for the allocation? Won't it cause some runtime error later, asthis->get_allocator()
won't deallocate the memory properly?
Because the assignment propagates the allocator: after the assignment, this->get_allocator()
is a copy of other.get_allocator()
, so it can safely deallocate memory allocated by it.
If
this->get_allocator() == other.get_allocator()
, this is an easy task. But if not, the same questions above follow, except in this case move-assignment is used.
Actually, this is completely different. Move assignment with a POCMA allocator is trivial: you destroy all the elements in *this
, free the memory, and plunder the memory and allocator of other
.
The only case where container move assignment has to resort to element-wise move assignment/construction is when you have a non-POCMA allocator and the allocators compare unequal. In that case, all allocation and construction are done with this->get_allocator()
since you don't propagate anything.
In both cases, I have an additional question. If the elements can neither be copy-assigned or move-assigned, is it okay to destroy it and construct from other? If it is, whose allocator should I use?
Destroy it using the allocator it was originally constructed with; construct it using the allocator it will be destroyed with. In other words, if you are propagating the allocator, then destroy it with the target allocator and construct with the source allocator.