Title
Missing SFINAE rule in unique_ptr templated assignment
Status
resolved
Section
[unique.ptr.single.asgn]
Submitter
Geoffrey Romer

Created on 2012-12-20.00:00:00 last changed 109 months ago

Messages

Date: 2015-05-06.18:35:04

Proposed resolution:

Resolved by accepting N4366.

Date: 2015-05-06.18:35:04

[ 2015-05, Lenexa ]

Straw poll: send N4366 to full committee, with both fixes from the sections "What is the correct fix?" and "unique_ptr<T[]> needs the correct fix too"

Date: 2015-02-27.07:52:15

[ 2015-05-18, Howard comments ]

Updated proposed wording has been provided in N4366.

Date: 2013-03-15.00:00:00

[ 2013-03-15 Issues Teleconference ]

Moved to Review.

The wording looks good, but we want a little more time than the telecon permits to be truly comfortable. We expect this issue to resolve fairly easily in Bristol.

Date: 2015-05-06.18:35:04

[unique.ptr.single.asgn]/5 permits unique_ptr's templated assignment operator to participate in overload resolution even when incompatibilities between D and E will render the result ill-formed, but the corresponding templated copy constructor is removed from the overload set in those situations (see the third bullet point of [unique.ptr.single.ctor]/19). This asymmetry is confusing, and presumably unintended; it may lead to situations where constructing one unique_ptr from another is well-formed, but assigning from the same unique_ptr would be ill-formed.

There is a slight coupling between this and LWG 2118, in that my PR for LWG 2118 incorporates equivalent wording in the specification of the templated assignment operator for the array specialization; the two PRs are logically independent, but if my PR for 2118 is accepted but the above PR is not, the discrepancy between the base template and the specialization could be confusing.

Previous resolution [SUPERSEDED]:

This wording is relative to N3485.

  1. Revise [unique.ptr.single.asgn] p5 as follows:

    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
    

    -4- Requires: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be well-formed and shall not throw an exception. Otherwise, E is a reference type and assignment of the deleter from an lvalue of type E shall be well-formed and shall not throw an exception.

    -5- Remarks: This operator shall not participate in overload resolution unless:

    • unique_ptr<U, E>::pointer is implicitly convertible to pointer and

    • U is not an array type., and

    • either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.

    -6- Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by an assignment from std::forward<E>(u.get_deleter()).

    -7- Returns: *this.

History
Date User Action Args
2015-05-06 18:35:04adminsetmessages: + msg7364
2015-05-06 18:35:04adminsetstatus: review -> resolved
2015-02-27 07:52:15adminsetmessages: + msg7233
2013-03-18 14:33:00adminsetmessages: + msg6437
2013-03-18 13:02:36adminsetstatus: new -> review
2012-12-21 20:27:35adminsetmessages: + msg6307
2012-12-20 00:00:00admincreate