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.
construct
/destroy
in allocate_shared
Section: 20.3.2.2.7 [util.smartptr.shared.create] Status: New Submitter: Billy O'Neal III Opened: 2019-06-11 Last modified: 2020-09-06
Priority: 3
View other active issues in [util.smartptr.shared.create].
View all other issues in [util.smartptr.shared.create].
View all issues with New status.
Discussion:
The new allocate_shared
wording says we need to rebind the allocator back to T
's
type before we can call construct
or destroy
, but this is suboptimal (might make
extra unnecessary allocator copies), and is inconsistent with the containers' behavior, which call
allocator construct
on whatever T
they want. (For example,
std::list<T, alloc<T>>
rebinds to alloc<_ListNode<T>>
,
but calls construct(T*)
without rebinding back)
[2019-07 Issue Prioritization]
Priority to 3 after discussion on the reflector.
Proposed resolution:
This wording is relative to N4810.
Modify 20.3.2.2.7 [util.smartptr.shared.create] as indicated:
[Drafting note: The edits to change
pv
topu
were suggested by Jonathan Wakely (thanks!). This wording also has theremove_cv_t
fixes specified by LWG 3210 — if that change is rejected some of those have to be stripped here.]
template<class T, ...> shared_ptr<T> make_shared(args); template<class T, class A, ...> shared_ptr<T> allocate_shared(const A& a, args); template<class T, ...> shared_ptr<T> make_shared_default_init(args); template<class T, class A, ...> shared_ptr<T> allocate_shared_default_init(const A& a, args);-2- Requires: […]
[…] -7- Remarks:
(7.1) — […]
[…]
(7.5) — When a (sub)object of a non-array type
U
is specified to have an initial value ofv
, orU(l...)
, wherel...
is a list of constructor arguments,allocate_shared
shall initialize this (sub)object via the expression
(7.5.1) —
allocator_traits<A2>::construct(a2, p
orvu, v)(7.5.2) —
allocator_traits<A2>::construct(a2, p
vu, l...)respectively, where
p
is a pointer of typevuremove_cv_t<U>*
pointsing to storage suitable to hold an object of typeremove_cv_t<U>
anda2
of typeA2
is a potentially rebound copy of the allocatora
passed toallocate_shared
such that its.value_type
isremove_cv_t<U>
(7.6) — […]
(7.7) — When a (sub)object of non-array type
U
is specified to have a default initial value,allocate_shared
shallinitializes this (sub)object via the expressionallocator_traits<A2>::construct(a2, p
, wherevu)p
is a pointer of typevuremove_cv_t<U>*
pointsing to storage suitable to hold an object of typeremove_cv_t<U>
anda2
of typeA2
is a potentially rebound copy of the allocatora
passed toallocate_shared
such that its.value_type
isremove_cv_t<U>
[…]
(7.12) — When a (sub)object of non-array type
U
that was initialized byallocate_shared
is to be destroyed, it is destroyed via the expressionallocator_traits<A2>::destroy(a2, p
wherevu)p
is a pointer of typevuremove_cv_t<U>*
pointsing to that object of typeremove_cv_t<U>
anda2
of typeA2
is a potentially rebound copy of the allocatora
passed toallocate_shared
such that its.value_type
isremove_cv_t<U>