Encapsulates strategies for access/addressing, allocation/deallocation and construction/destruction of objects.
Every standard library component that may need to allocate or release storage, from std::string, std::vector, and every container, except std::array(since C++11) and std::inplace_vector(since C++26), to std::shared_ptr and std::function(until C++17), does so through an Allocator: an object of a class type that satisfies the following requirements.
The implementation of many allocator requirements is optional because all AllocatorAwareContainer access allocators indirectly through std::allocator_traits, and std::allocator_traits supplies the default implementation of those requirements.
[edit] RequirementsGiven
T
, a non-const, non-reference type(until C++11)non-const object type(since C++11)(until C++17)cv-unqualified object type(since C++17),A
, an Allocator type for type T
,A
,B
, the corresponding Allocator type for some cv-unqualified object type U
(as obtained by rebinding A
),B
,X
,T
obtained by the expression *p,A::pointer
(optional) (unspecified)[1]
A::const_pointer
(optional) (unspecified)
A::pointer
is convertible to A::const_pointer
.A::void_pointer
(optional) (unspecified)
A::pointer
is convertible to A::void_pointer
.B::void_pointer
and A::void_pointer
are the same type.A::const_void_pointer
(optional) (unspecified)
A::pointer
, A::const_pointer
, and A::void_pointer
are convertible to A::const_void_pointer
.B::const_void_pointer
and A::const_void_pointer
are the same type.A::value_type
T
A::size_type
(optional) (unspecified)
A
can allocate.A::difference_type
(optional) (unspecified)
A
.A::template rebind<U>::other
B
U
, B::template rebind<T>::other
is A
.T&
*cp const T& *cp and *p identify the same object. p->m (as is) Same as (*p).m, if (*p).m is well-defined. cp->m (as is) Same as (*cp).m, if (*cp).m is well-defined. static_cast<A::pointer>(vp) (as is) static_cast<A::pointer>(vp) == p static_cast<A::const_pointer>(cvp) (as is) static_cast<A::const_pointer>(cvp) == cp std::pointer_traits<A::pointer>::pointer_to(r) (as is) Storage and lifetime operations Expression Return type Requirements a.allocate(n) A::pointer
Allocates storage suitable for an array object of type T[n]
and creates the array, but does not construct array elements. May throw exceptions. If n == 0, the return value is unspecified. a.allocate(n, cvp) (optional) Same as a.allocate(n), but may use cvp (nullptr or a pointer obtained from a.allocate()) in unspecified manner to aid locality. a.allocate_at_least(n) (optional) (since C++23) std::allocation_result
<A::pointer>
Allocates storage suitable for an array object of typeT[cnt]
and creates the array, but does not construct array elements, then returns {p, cnt}, where p points to the storage and cnt is not less than n. May throw exceptions. a.deallocate(p, n) (not used) Deallocates storage pointed to p, which must be a value returned by a previous call to allocate
or allocate_at_least
(since C++23) that has not been invalidated by an intervening call to deallocate
. n must match the value previously passed to allocate
or be between the request and returned number of elements via allocate_at_least
(may be equal to either bound)(since C++23). Does not throw exceptions. a.max_size() (optional) A::size_type
The largest value that can be passed to A::allocate(). a.construct(xp, args...) (optional) (not used) Constructs an object of type X
in previously-allocated storage at the address pointed to by xp, using args... as the constructor arguments. a.destroy(xp) (optional) (not used) Destructs an object of type X
pointed to by xp, but does not deallocate any storage. Relationship between instances Expression Return type Requirements a1 == a2 bool
rebind
maintain each other's resources, such as memory pools.)
A::is_always_equal
A
always compare equal.A
A
to be used by the container that is copy-constructed from the one that uses a currently.A
.)A::propagate_on_container_copy_assignment
A
needs to be copied when the container that uses it is copy-assigned.A
must satisfy CopyAssignable and the copy operation must not throw exceptions.A::propagate_on_container_move_assignment
A
needs to be moved when the container that uses it is move-assigned.A
must satisfy MoveAssignable and the move operation must not throw exceptions.A::propagate_on_container_swap
A
need to be swapped when two containers that use them are swapped.A
must satisfy Swappable and the swap operation must not throw exceptions.Notes:
rebind
is only optional (provided by std::allocator_traits) if this allocator is a template of the form SomeAllocator<T, Args>
, where Args
is zero or more additional template type parameters.Given
X::void_pointer
, X::const_void_pointer
, X::pointer
, or X::const_pointer
X::const_pointer
, using a sequence of static_casts using only these four types, and the expression px1 == px2 evaluates to true.
Given
X::void_pointer
X::const_void_pointer
with no change in semantics.
Given
X::pointer
X::const_pointer
with no change in semantics.
The above requirements make it possible to compare Container's iterator
s and const_iterator
s.
An allocator type X
for type T
additionally satisfies the allocator completeness requirements if both of the following are true regardless of whether T
is a complete type:
X
is a complete type.value_type
, all the member types of std::allocator_traits<X> are complete types.Every Allocator type is either stateful or stateless. Generally, a stateful allocator type can have unequal values which denote distinct memory resources, while a stateless allocator type denotes a single memory resource.
Although custom allocators are not required to be stateless, whether and how the use of stateful allocators in the standard library is implementation-defined. Use of unequal allocator values may result in implementation-defined runtime errors or undefined behavior if the implementation does not support such usage.
(until C++11)Custom allocators may contain state. Each container or another allocator-aware object stores an instance of the supplied allocator and controls allocator replacement through std::allocator_traits.
(since C++11)Instances of a stateless allocator type always compare equal. Stateless allocator types are typically implemented as empty classes and suitable for empty base class optimization.
The member type is_always_equal
of std::allocator_traits is intendedly used for determining whether an allocator type is stateless.
When the member type pointer
is not a raw pointer type, it is commonly referred to as a "fancy pointer". Such pointers were introduced to support segmented memory architectures and are used today to access objects allocated in address spaces that differ from the homogeneous virtual address space that is accessed by raw pointers. An example of a fancy pointer is the mapping address-independent pointer boost::interprocess::offset_ptr
, which makes it possible to allocate node-based data structures such as std::set in shared memory and memory mapped files mapped in different addresses in every process. Fancy pointers can be used independently of the allocator that provided them, through the class template std::pointer_traits(since C++11). The function std::to_address can be used to obtain a raw pointer from a fancy pointer.(since C++20)
Use of fancy pointers and customized size/different type in the standard libary are conditionally supported. Implementations may require that member type pointer
, const_pointer
, size_type
, and difference_type
are value_type*
, const value_type*, std::size_t, and std::ptrdiff_t, respectively.
For the definition of the query object std::get_allocator, the following exposition-only concept is defined.
The exposition-only concept /*simple-allocator*/ defines the minimal usability constraints of the Allocator requirement.
(since C++26) [edit] Standard libraryThe following standard library components satisfy the Allocator requirements:
[edit] ExamplesDemonstrates a C++11 allocator, except for [[nodiscard]]
added to match C++20 style.
#include <cstdlib> #include <iostream> #include <limits> #include <new> #include <vector> template<class T> struct Mallocator { typedef T value_type; Mallocator() = default; template<class U> constexpr Mallocator(const Mallocator <U>&) noexcept {} [[nodiscard]] T* allocate(std::size_t n) { if (n > std::numeric_limits<std::size_t>::max() / sizeof(T)) throw std::bad_array_new_length(); if (auto p = static_cast<T*>(std::malloc(n * sizeof(T)))) { report(p, n); return p; } throw std::bad_alloc(); } void deallocate(T* p, std::size_t n) noexcept { report(p, n, 0); std::free(p); } private: void report(T* p, std::size_t n, bool alloc = true) const { std::cout << (alloc ? "Alloc: " : "Dealloc: ") << sizeof(T) * n << " bytes at " << std::hex << std::showbase << reinterpret_cast<void*>(p) << std::dec << '\n'; } }; template<class T, class U> bool operator==(const Mallocator <T>&, const Mallocator <U>&) { return true; } template<class T, class U> bool operator!=(const Mallocator <T>&, const Mallocator <U>&) { return false; } int main() { std::vector<int, Mallocator<int>> v(8); v.push_back(42); }
Possible output:
Alloc: 32 bytes at 0x2020c20 Alloc: 64 bytes at 0x2023c60 Dealloc: 32 bytes at 0x2020c20 Dealloc: 64 bytes at 0x2023c60[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 179 C++98pointer
and const_pointer
were not
T
could be a const-qualified type or reference type,
is_always_equal
provided LWG 2263 C++11 the resolution of LWG issue 179 was accidently dropped in C++11
void_pointer
and const_void_pointer
restored and generalized LWG 2447 C++11 T
could be a volatile-qualified object type prohibited these types LWG 2593 C++11 moving from an allocator might modify its value modification forbidden P0593R6 C++98 allocate
were not required to create an
reference
and const_reference
of std::allocator are defined as T&
and const T&
respectively.
T
is a reference type, reference
and const_reference
are ill-formed because reference to reference cannot be formed (reference collapsing was introduced in C++11).T
is const-qualified, reference
and const_reference
are the same, and the overload set of address() is ill-formed.RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4