The old C++ standard makes requirements for a standard-compliant allocator: These requirements include that if you have Alloc<T> a, b
, then a == b
, and you can use b
to deallocate things that were allocated with a
. Allocators are fundamentally stateless.
In C++11, the situation got a lot more involved, as there is now support for stateful allocators. As you copy and move objects around, there are specific rules whether one container can be copied or moved from another container if the allocators differ, and how the allocators get copied or moved.
Just to answer your question first: No, you can definitely not assume that it makes sense to copy your allocator around, and your allocator may not even be copyable.
Here is 23.2.1/7 on this subject:
Unless otherwise specified, all containers defined in this clause obtain memory using an allocator (see 17.6.3.5). Copy constructors for these container types obtain an allocator by calling allocator_traits<allocator_-type>::select_on_container_copy_construction
on their first parameters. Move constructors obtain an allocator by move construction from the allocator belonging to the container being moved. Such move construction of the allocator shall not exit via an exception. All other constructors for these container types take an Allocator&
argument (17.6.3.5), an allocator whose value type is the same as the container’s value type. [Note: If an invocation of a constructor uses the default value of an optional allocator argument, then the Allocator type must support value initialization. —end note] A copy of this allocator is used for any memory allocation performed, by these constructors and by all member functions, during the lifetime of each container object or until the allocator is replaced. The allocator may be replaced only via assignment or
swap(). Allocator replacement is performed by copy assignment, move assignment, or swapping of the allocator only if allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value
,
allocator_traits<allocator_type>::propagate_on_container_move_assignment::value
, or allocator_traits<allocator_type>::propagate_on_container_swap::value
is true within the implementation of the corresponding container operation. The behavior of a call to a container’s swap function is undefined unless the objects being swapped have allocators that compare equal or allocator_traits<allocator_type>::propagate_on_container_swap::value
is true. In all container types defined in this Clause, the member get_allocator()
returns a copy of the allocator used to construct the container or, if that allocator has been replaced, a copy of the most recent replacement.
See also the documentation of std::allocator_traits
for a synopsis.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…