C++ named requirements: AllocatorAwareContainer (since C++11)

From cppreference.com

An

AllocatorAwareContainer

is a

Container

that holds an instance of an

Allocator

and uses that instance in all its member functions to allocate and deallocate memory and to construct and destroy objects in that memory (such objects may be container elements, nodes, or, for unordered containers, bucket arrays), except that

std::basic_string

specializations do not use the allocators for construction/destruction of their elements(since C++23).

The following rules apply to container construction:

Copy constructors of AllocatorAwareContainers obtain their instances of the allocator by calling std::allocator_traits<allocator_type>::select_on_container_copy_construction on the allocator of the container being copied.

Move constructors obtain their instances of allocators by move-constructing from the allocator belonging to the old container.

All other constructors take a constallocator_type& parameter.

The only way to replace an allocator is copy-assignment, move-assignment, and swap:

Copy-assignment will replace the allocator only if std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value is true.

Move-assignment will replace the allocator only if std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value is true.

Swap will replace the allocator only if std::allocator_traits<allocator_type>::propagate_on_container_swap::value is true. Specifically, it will exchange the allocator instances through an unqualified call to the non-member function swap, see

Swappable

.

Note: The behavior of swapping two containers with unequal allocators if propagate_on_container_swap is false is undefined.

The accessor get_allocator() obtains a copy of the allocator that was used to construct the container or installed by the most recent allocator replacement operation.

Requirements

A type satisfies AllocatorAwareContainer if it satisfies

Container

and, given the following types and values, the semantic and complexity requirements in the tables below are satisfied:

Type Definition Xan AllocatorAwareContainer type Tthe value_type of XAthe allocator type used by XValue Definition a, bnon-const lvalues of type Xcan lvalue of type constXtan lvalue or a const rvalue of type Xrva non-const rvalue of type Xma value of type ATypes

Name Type Requirement typenameX::allocator_typeAX::allocator_type::value_type and X::value_type are the same. Statements

Statement Semantics Complexity Xu;
Xu=X();Precondition A is

DefaultConstructible

. Constant Postcondition u.empty() and u.get_allocator()==A() are both true. Xu(m);Postcondition u.empty() and u.get_allocator()==m are both true. Constant Xu(t,m);Precondition T is

CopyInsertable

into X. Linear Postcondition u==t and u.get_allocator()==m are both true. Xu(rv);Postcondition u has the same elements as rv had before this construction.

The value of u.get_allocator() is the same as the value of rv.get_allocator() before this construction.

Constant Xu(rv,m);Precondition T is

MoveInsertable

into X. Constant if m==rv.get_allocator() is true.

Otherwise linear.

Postcondition u has the same elements, or copies of the elements, that rv had before this construction.

u.get_allocator()==m is true.

Expressions

Expression Type Semantics Complexity c.get_allocator()ANo direct semantic requirement. Constant a=tX&Precondition T is

CopyInsertable

into X and

CopyAssignable

. Linear Postcondition a==t is true. a=rvX&Precondition If the allocator will not be replaced by move-assignment (see

above

), then T is

MoveInsertable

into X and

MoveAssignable

. Linear Effect All existing elements of a are either move assigned to or destroyed. Postcondition If a and rv do not refer the same object, a is equal to the value that rv had before the assignment. a.swap(b)voidEffect Exchanges the contents of a and b. Constant Notes

AllocatorAwareContainers always call std::allocator_traits<A>::construct(m,p,args) to construct an object of type T at p using args, with m==get_allocator(). The default construct in

std::allocator

calls ::new((void*)p)T(args)(until C++20)

std::allocator

has no construct member and std::construct_at(p,args) is called when constructing elements(since C++20), but specialized allocators may choose a different definition.

Standard library

All standard library string types and containers (except

std::array

and std::inplace_vector) are AllocatorAwareContainers:

basic_string

stores and manipulates sequences of characters
(class template)

[edit]

deque

double-ended queue
(class template)

[edit]

forward_list

(C++11)

singly-linked list
(class template)

[edit]

list

doubly-linked list
(class template)

[edit]

vector

resizable contiguous array
(class template)

[edit]

map

collection of key-value pairs, sorted by keys, keys are unique
(class template)

[edit]

multimap

collection of key-value pairs, sorted by keys
(class template)

[edit]

set

collection of unique keys, sorted by keys
(class template)

[edit]

multiset

collection of keys, sorted by keys
(class template)

[edit]

unordered_map

(C++11)

collection of key-value pairs, hashed by keys, keys are unique
(class template)

[edit]

unordered_multimap

(C++11)

collection of key-value pairs, hashed by keys
(class template)

[edit]

unordered_set

(C++11)

collection of unique keys, hashed by keys
(class template)

[edit]

unordered_multiset

(C++11)

collection of keys, hashed by keys
(class template)

[edit]

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior

LWG 2839

C++11 self move assignment of standard containers was not allowed allowed but the result is unspecified