This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD status.
unique_ptr
with reference deleterSection: 20.3.1.3.2 [unique.ptr.single.ctor] Status: NAD Submitter: Jonathan Wakely Opened: 2018-10-09 Last modified: 2018-11-27
Priority: Not Prioritized
View all other issues in [unique.ptr.single.ctor].
View all issues with NAD status.
Discussion:
[unique.ptr.single.ctor] defines these constructors:
unique_ptr(pointer p, const D& d) noexcept; unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept;
and p13 says:
Remarks: If
D
is a reference type, the second constructor is defined as deleted. These constructors shall not participate in overload resolution unlessis_constructible_v<D, decltype(d)>
is true.
The first sentence in the Remarks has no effect. If D
is a reference
type A&
, then for the second constructor the condition is
is_constructible<A&, A&&>
which is false
. So the
second constructor never participates in overload resolution for reference deleters, and
so it's irrelevant whether it's deleted or not.
is_constructible
constraint so that the deleted constructor participates in overload
resolution for deleters of reference type. That way trying to
initialize a deleter of reference type from an rvalue will resolve to
the deleted function as intended.
I think we can just change the "shall not participate" condition to only apply to
non-reference deleters. For reference deleters the condition is always true for the
first constructor, because is_constructible<A&, A&>
is
true
, and always false
for the second constructor (but we want
it to be true so the deleted constructor is used). So for both constructors, the
"shall not participate" isn't useful when D
is a reference type.
11-2018 Status to NAD after discussion on the reflector.
Proposed resolution:
This wording is relative to N4778.
Change 20.3.1.3.2 [unique.ptr.single.ctor] as indicated:
unique_ptr(pointer p, const D& d) noexcept; unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept;[…]
-11- Remarks: IfD
is a reference type, the second constructor is defined as deleted. IfD
is not a reference type, tThese constructors shall not participate in overload resolution unlessis_constructible_v<D, decltype(d)>
istrue
. […]