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

### 3007. `allocate_shared` should rebind allocator to cv-unqualified `value_type` for construction

Section: 20.11.3.7 [util.smartptr.shared.create] Status: C++20 Submitter: Glen Joseph Fernandes Opened: 2017-08-06 Last modified: 2021-02-25

Priority: 0

View other active issues in [util.smartptr.shared.create].

View all other issues in [util.smartptr.shared.create].

View all issues with C++20 status.

Discussion:

The remarks for the `allocate_shared` family of functions specify that when constructing a (sub)object of type `U`, it uses a rebound copy of the allocator `a` passed to `allocate_shared` such that its `value_type` is `U`. However `U` can be a `const` or `volatile` qualified type, and [allocator.requirements] specify that the `value_type` must be cv-unqualified.

[ 2017-11-01 Moved to Tentatively Ready after 6 positive votes for P0 on c++std-lib. ]

[2018-3-17 Adopted in Jacksonville]

Proposed resolution:

This resolution is relative to N4687.

1. Edit 20.11.3.7 [util.smartptr.shared.create] as indicated:

   >     template<class T, ...>
   >     shared_ptr<T> make_shared(args);
   >     template<class T, class A, ...>
   >     shared_ptr<T> allocate_shared(const A& a, args);

   > > […]

   > > -7- Remarks:

   > > 1. […]

   > > 2. (7.5) — When a (sub)object of a non-array type `U` is specified to have an initial value of `v`, or `U(l...)`, where `l...` is a list of constructor arguments, `allocate_shared` shall initialize this (sub)object via the expression

   > >    1. (7.5.1) — `allocator_traits<A2>::construct(a2, pv, v)` or

   > >    2. (7.5.2) — `allocator_traits<A2>::construct(a2, pv, l...)`

   > >    respectively, where `pv` points to storage suitable to hold an object of type `U` and `a2` of type `A2` is a rebound copy of the allocator a passed to `allocate_shared` such that its `value_type` is `remove_cv_t<U>`.

   > > 3. (7.6) — When a (sub)object of non-array type `U` is specified to have a default initial value, `make_shared` shall initialize this (sub)object via the expression `::new(pv) U()`, where `pv` has type `void*` and points to storage suitable to hold an object of type `U`.

   > > 4. (7.7) — When a (sub)object of non-array type `U` is specified to have a default initial value, `allocate_shared` shall initialize this (sub)object via the expression `allocator_traits<A2>::construct(a2, pv)`, where `pv` points to storage suitable to hold an object of type `U` and `a2` of type `A2` is a rebound copy of the allocator a passed to `allocate_shared` such that its `value_type` is `remove_cv_t<U>`.

   > > 5. […]