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.

### 3164. Unhelpful "shall not participate" constraints for `unique_ptr` with reference deleter

Section: 20.11.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 unless `is_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.

We should either strike that sentence, or adjust the `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.

1. Change 20.11.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: If `D` is a reference type, the second constructor is defined as deleted. If `D` is not a reference type, t These constructors shall not participate in overload resolution unless `is_constructible_v<D, decltype(d)>` is `true`.

   > > […]