How is allocator-aware container assignment implemented?

前端 未结 2 1097
清歌不尽
清歌不尽 2021-02-10 15:56

For example, from std::deque::operator = in C++ Reference:
(1) Copy Assignment (const std::deque &other)

2条回答
  •  时光取名叫无心
    2021-02-10 16:17

    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, using other.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, as this->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.

提交回复
热议问题