This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4311. Can std::pmr::polymorphic_allocator::construct just call std::uninitialized_construct_using_allocator?

Section: 20.5.3.3 [mem.poly.allocator.mem] Status: New Submitter: Jiang An Opened: 2025-08-06 Last modified: 2025-08-09

Priority: Not Prioritized

View all other issues in [mem.poly.allocator.mem].

View all issues with New status.

Discussion:

This is closely related to LWG 3901(i) but only affects arguably pathological cases.

Uses-allocator construction for cv-qualified types needs to be well-formed, but it's questionable to require polymorphic_allocator::construct to support constructing objects via pointer to a cv-qualified type. LWG 3870(i) banned such placement construction for std::construct_at, which is depended by uninitialized_construct_using_allocator.

As a result, it seems non-conforming to just use uninitialized_construct_using_allocator in polymorphic_allocator::construct since C++20, because the latter is still required to handle cv-qualified target types. If the status quo is considered unintended and needed to be fixed, perhaps we can just respecify polymorphic_allocator::construct to use uninitialized_construct_using_allocator.

Proposed resolution:

This wording is relative to this CD preview draft.

[Drafting note: The Mandates: element allows implementations not to add constraints even if uninitialized_construct_using_allocator is constrained in the future. The Throws: element is made redundant by "Effects: Equivalent to", and it's already wrong because the exception can be thrown by a conversion function.]

  1. Modify 20.5.3.3 [mem.poly.allocator.mem] as indicated:

    template<class T, class... Args>
      void construct(T* p, Args&&... args);
    

    -14- Mandates: Uses-allocator construction of T with allocator *this (see 20.2.8.2 [allocator.uses.construction]) and constructor arguments std::forward<Args>(args)...uninitialized_construct_using_allocator(p, *this, std::forward<Args>(args)...) is well-formed.

    -15- Effects: Constructs a T object in the storage whose address is represented by p by uses-allocator construction with allocator *this and constructor arguments std::forward<Args>(args)....Equivalent to:

     
    uninitialized_construct_using_allocator(p, *this, std::forward<Args>(args)...);
    

    -16- Throws: Nothing unless the constructor for T throws.