Title
Unhelpful "shall not participate" constraints for unique_ptr with reference deleter
Status
nad
Section
[unique.ptr.single.ctor]
Submitter
Jonathan Wakely

Created on 2018-10-09.00:00:00 last changed 65 months ago

Messages

Date: 2018-10-13.19:14:46

Proposed resolution:

This wording is relative to N4778.

  1. Change [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, tThese constructors shall not participate in overload resolution unless is_constructible_v<D, decltype(d)> is true.

    […]

Date: 2018-11-27.04:34:19

[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.

History
Date User Action Args
2018-11-27 04:34:19adminsetstatus: new -> nad
2018-10-13 19:14:46adminsetmessages: + msg10165
2018-10-09 00:00:00admincreate