Short form: We propose to add library functions that allow the systematic use of allocators as a customisation point for dynamic allocations. The new functions complete the following picture:
| using operator {new,delete} | using allocator | |
|---|---|---|
| Manual | T * p = new T(args...) | auto p = allocate_new<T>(alloc, args...) | 
| delete p | allocate_delete(alloc, p) | |
| Unique pointer | make_unique<T>(args...) | allocate_unique<T>(alloc, args...) | 
| default_delete<T> | allocator_delete<T> | |
| Shared pointer | make_shared<T>(args...) | allocate_shared<T>(alloc, args...) | 
Long form: The standard library rarely uses
      new/delete directly, but instead allows customisation of dynamic
      allocation and object construction via allocators. Currently this customisation is only
      available for container elements and for shared_ptr (as well as for
      a few other types that require dynamically allocated memory), but not for the top-level
      objects themselves.
The proposal is to complete the library facilities for
      allocator-based customisation by providing a direct mechanism for creating and destroying
      a dynamically stored object through an allocator, as well as a new deleter type for
      unique_ptr to hold an allocator-managed unique pointee, together with the
      appropriate factory function.
std::allocate_unique<std::vector<T,
        ScopedArenaAlloc<T>>>(arena_alloc) allows this. (Here we assume the
        use of the usual alias idiom template <typename T> using ScopedArenaAlloc =
        std::scoped_allocator_adaptor<ArenaAlloc<T>>;).auto p =
        std::allocate_new<std::vector<T,
        ScopedShmemAlloc<T>>>(shmem_alloc). The returned pointer is
        presumably an offset pointer, and its offset value needs to be communicated to the other
        participating processes. The last process to use the container calls
        allocate_delete(shmem_alloc, p).To allow std::unique_ptr to use custom allocators, we first need a deleter template that stores the allocator:
The factory function is:
The type T must not be an array type.
noexcept).allocate_new take an explicit typename T
        as a parameter, or use A::value_type?allocate_delete for both for the function
        template that replaces delete and for the class template that replaces
        default_delete to keep using the word “allocate” consistently.
        That would require saying the unwieldy struct allocate_delete in the
        allocate_unique function template, though.