Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      C++ named requirements:Allocator

      From cppreference.com
      <cpp‎ |named req
       
       
      C++ named requirements
       

      Encapsulates strategies for access/addressing, allocation/deallocation and construction/destruction of objects.

      Every standard library component that may need to allocate or release storage, fromstd::string,std::vector, and every container, exceptstd::array(since C++11) andstd::inplace_vector(since C++26), tostd::shared_ptr andstd::function(until C++17), does so through anAllocator: an object of a class type that satisfies the following requirements.

      The implementation of many allocator requirements is optional because allAllocatorAwareContainer access allocators indirectly throughstd::allocator_traits, andstd::allocator_traits supplies the default implementation of those requirements.

      Contents

      [edit]Requirements

      Given

      • T, anon-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, anAllocator type for typeT,
      • a, an object of typeA,
      • B, the correspondingAllocator type for some cv-unqualified object typeU (as obtained by rebindingA),
      • b, an object of typeB,
      • p, a value of typestd::allocator_traits<A>::pointer, obtained by callingstd::allocator_traits<A>::allocate(),
      • cp, a value of typestd::allocator_traits<A>::const_pointer, obtained by conversion fromp,
      • vp, a value of typestd::allocator_traits<A>::void_pointer, obtained by conversion fromp,
      • cvp, a value of typestd::allocator_traits<A>::const_void_pointer, obtained by conversion fromcp or fromvp,
      • xp, a dereferenceable pointer to some cv-unqualified object typeX,
      • r, an lvalue of typeT obtained by the expression*p,
      • n, a value of typestd::allocator_traits<A>::size_type.
      Inner types
      Type-idAliased typeRequirements
      A::pointer(optional)(unspecified)[1]
      A::const_pointer(optional)(unspecified)
      A::void_pointer(optional)(unspecified)
      • SatisfiesNullablePointer.
      • A::pointer is convertible toA::void_pointer.
      • B::void_pointer andA::void_pointer are the same type.
      A::const_void_pointer(optional)(unspecified)
      • SatisfiesNullablePointer.
      • A::pointer,A::const_pointer, andA::void_pointer are convertible toA::const_void_pointer.
      • B::const_void_pointer andA::const_void_pointer are the same type.
      A::value_typeT
      A::size_type(optional)(unspecified)
      • An unsigned integer type.
      • Can represent the size of the largest objectA can allocate.
      A::difference_type(optional)(unspecified)
      • A signed integer type.
      • Can represent the difference of any two pointers to the objects allocated byA.
      A::template rebind<U>::other
      (optional)[2]
      B
      • For anyU,B::template rebind<T>::other isA.
      Operations on pointers
      ExpressionReturn typeRequirements
      *pT&
      *cpconst 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
      ExpressionReturn typeRequirements
      a.allocate(n)A::pointerAllocates storage suitable for an array object of typeT[n] and creates the array, but does not construct array elements. May throw exceptions. Ifn==0, the return value is unspecified.
      a.allocate(n, cvp)(optional)Same asa.allocate(n), but may usecvp (nullptr or a pointer obtained froma.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}, wherep points to the storage andcnt is not less thann. May throw exceptions.
      a.deallocate(p, n)(not used)Deallocates storage pointed top, which must be a value returned by a previous call toallocateorallocate_at_least(since C++23) that has not been invalidated by an intervening call todeallocate.n must match the value previously passed toallocateor be between the request and returned number of elements viaallocate_at_least (may be equal to either bound)(since C++23). Does not throw exceptions.
      a.max_size()(optional)A::size_typeThe largest value that can be passed toA::allocate().
      a.construct(xp, args...)(optional)(not used)Constructs an object of typeX in previously-allocated storage at the address pointed to byxp, usingargs... as the constructor arguments.
      a.destroy(xp)(optional)(not used)Destructs an object of typeX pointed to byxp, but does not deallocate any storage.
      Relationship between instances
      ExpressionReturn typeRequirements
      a1== a2bool
      • true only if the storage allocated by the allocatora1 can be deallocated througha2.
      • Establishes reflexive, symmetric, and transitive relationship.
      • Does not throw exceptions.
      a1!= a2
      • Same as!(a1== a2).
      DeclarationEffectRequirements
      A a1(a)Copy-constructsa1 such thata1== a.
      (Note: EveryAllocator also satisfiesCopyConstructible.)
      • Does not throw exceptions.
      A a1= a
      A a(b)Constructsa such thatB(a)== b andA(b)== a.
      (Note: This implies that all allocators related byrebind maintain each other's resources, such as memory pools.)
      • Does not throw exceptions.
      A a1(std::move(a))Constructsa1 such that it equals the prior value ofa.
      • Does not throw exceptions.
      • The value ofa is unchanged anda1== a.
      A a1= std::move(a)
      A a(std::move(b))Constructsa such that it equals the prior value ofA(b).
      • Does not throw exceptions.
      Type-idAliased typeRequirements
      A::is_always_equal
      (optional)
      std::true_type orstd::false_type or derived from such.
      Influence on container operations
      ExpressionReturn typeDescription
      a.select_on_container_copy_construction()
      (optional)
      A
      • Provides an instance ofA to be used by the container that is copy-constructed from the one that usesa currently.
      • (Usually returns either a copy ofa or a default-constructedA.)
      Type-idAliased typeDescription
      A::propagate_on_container_copy_assignment
      (optional)
      std::true_type orstd::false_type or derived from such.
      • std::true_type or derived from it if the allocator of typeA needs to be copied when the container that uses it is copy-assigned.
      • If this member isstd::true_type or derived from it, thenA must satisfyCopyAssignable and the copy operation must not throw exceptions.
      • Note that if the allocators of the source and the target containers do not compare equal, copy assignment has to deallocate the target's memory using the old allocator and then allocate it using the new allocator before copying the elements (and the allocator).
      A::propagate_on_container_move_assignment
      (optional)
      • std::true_type or derived from it if the allocator of typeA needs to be moved when the container that uses it is move-assigned.
      • If this member isstd::true_type or derived from it, thenA must satisfyMoveAssignable and the move operation must not throw exceptions.
      • If this member is not provided or derived fromstd::false_type and the allocators of the source and the target containers do not compare equal, move assignment cannot take ownership of the source memory and must move-assign or move-construct the elements individually, resizing its own memory as needed.
      A::propagate_on_container_swap
      (optional)
      • std::true_type or derived from it if the allocators of typeA need to be swapped when two containers that use them are swapped.
      • If this member isstd::true_type or derived from it, typeA must satisfySwappable and the swap operation must not throw exceptions.
      • If this member is not provided or derived fromstd::false_type and the allocators of the two containers do not compare equal, the behavior of container swap is undefined.

      Notes:

      1. See alsofancy pointers below.
      2. rebind is only optional (provided bystd::allocator_traits) if this allocator is a template of the formSomeAllocator<T, Args>, whereArgs is zero or more additional template type parameters.

      Given

      • x1 andx2, objects of (possibly different) typesX::void_pointer,X::const_void_pointer,X::pointer, orX::const_pointer
      Then,x1 andx2 areequivalently-valued pointer values, if and only if bothx1 andx2 can be explicitly converted to the two corresponding objectspx1 andpx2 of typeX::const_pointer, using a sequence ofstatic_casts using only these four types, and the expressionpx1== px2 evaluates totrue.

      Given

      • w1 andw2, objects of typeX::void_pointer
      Then, for the expressionw1== w2 andw1!= w2 either or both objects may be replaced by anequivalently-valued object of typeX::const_void_pointer with no change in semantics.

      Given

      • p1 andp2, objects of typeX::pointer
      Then, for the expressionsp1== p2,p1!= p2,p1< p2,p1<= p2,p1>= p2,p1> p2,p1- p2 either or both objects may be replaced by anequivalently-valued object of typeX::const_pointer with no change in semantics.

      The above requirements make it possible to compareContainer'siterators andconst_iterators.

      Allocator completeness requirements

      An allocator typeX for typeT additionally satisfies theallocator completeness requirements if both of the following are true regardless of whetherT is a complete type:

      • X is a complete type.
      • Except forvalue_type, all the member types ofstd::allocator_traits<X> are complete types.
      (since C++17)

      [edit]Stateful and stateless allocators

      EveryAllocator type is eitherstateful orstateless. 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 throughstd::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 forempty base class optimization.

      The member typeis_always_equal ofstd::allocator_traits is intendedly used for determining whether an allocator type is stateless.

      (since C++11)

      [edit]Fancy pointers

      When the member typepointer 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 pointerboost::interprocess::offset_ptr, which makes it possible to allocate node-based data structures such asstd::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 templatestd::pointer_traits(since C++11).The functionstd::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 typepointer,const_pointer,size_type, anddifference_type arevalue_type*,const value_type*,std::size_t, andstd::ptrdiff_t, respectively.

      (until C++11)

      Concept

      For the definition of the query objectstd::get_allocator, the following exposition-only concept is defined.

      template<class Alloc>

      concept/*simple-allocator*/= requires(Alloc alloc,std::size_t n)
      {
         {*alloc.allocate(n)}->std::same_as<typename Alloc::value_type&>;
         { alloc.deallocate(alloc.allocate(n), n)};  
      }&&std::copy_constructible<Alloc>

       &&std::equality_comparable<Alloc>;

      The exposition-only concept/*simple-allocator*/ defines the minimal usability constraints of theAllocator requirement.

      (since C++26)

      [edit]Standard library

      The following standard library components satisfy theAllocator requirements:

      the default allocator
      (class template)[edit]
      implements multi-level allocator for multi-level containers
      (class template)[edit]
      an allocator that supports run-time polymorphism based on thestd::pmr::memory_resource it is constructed with
      (class template)[edit]

      [edit]Examples

      Demonstrates a C++11 allocator, except for[[nodiscard]] added to match C++20 style.

      Run this code
      #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))throwstd::bad_array_new_length(); if(auto p=static_cast<T*>(std::malloc(n* sizeof(T)))){            report(p, n);return p;} throwstd::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>&){returntrue;} template<class T,class U>bool operator!=(const Mallocator<T>&,const Mallocator<U>&){returnfalse;} int main(){std::vector<int, Mallocator<int>> v(8);    v.push_back(42);}

      Possible output:

      Alloc: 32 bytes at 0x2020c20Alloc: 64 bytes at 0x2023c60Dealloc: 32 bytes at 0x2020c20Dealloc: 64 bytes at 0x2023c60

      [edit]Defect reports

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

      DRApplied toBehavior as publishedCorrect behavior
      LWG 179C++98pointer andconst_pointer were not
      required to be comparable with each other
      required
      LWG 199C++98the return value ofa.allocate(0) was unclearit is unspecified
      LWG 258
      (N2436)
      C++98the equality relationship between allocators were
      not required to be reflexive, symmetric or transitive
      required to be reflexive,
      symmetric and transitive
      LWG 274C++98T could be a const-qualified type or reference type,
      makingstd::allocator possibly ill-formed[1]
      prohibited these types
      LWG 2016C++11the copy, move and swap operations of
      allocator might be throwing when used
      required to be non-throwing
      LWG 2081C++98
      C++11
      allocators were not required to support copy
      assignment (C++98) and move assignment (C++11)
      required
      LWG 2108C++11there was no way to show an allocator is statelessis_always_equal provided
      LWG 2263C++11the resolution ofLWG issue 179 was accidently dropped in C++11
      and not generalized tovoid_pointer andconst_void_pointer
      restored and generalized
      LWG 2447C++11T could be a volatile-qualified object typeprohibited these types
      LWG 2593C++11moving from an allocator might modify its valuemodification forbidden
      P0593R6C++98allocate were not required to create an
      array object in the storage it allocated
      required
      1. The member typesreference andconst_reference ofstd::allocator are defined asT& andconst T& respectively.
        • IfT is a reference type,reference andconst_reference are ill-formed because reference to reference cannot be formed (reference collapsing was introduced in C++11).
        • IfT is const-qualified,reference andconst_reference are the same, and the overload set ofaddress() is ill-formed.
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/named_req/Allocator&oldid=177185"

      [8]ページ先頭

      ©2009-2025 Movatter.jp