This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

### 2228. Missing SFINAE rule in `unique_ptr` templated assignment

Section: 20.3.1.3.4 [unique.ptr.single.asgn] Status: Resolved Submitter: Geoffrey Romer Opened: 2012-12-20 Last modified: 2016-01-28

Priority: 3

View all other issues in [unique.ptr.single.asgn].

View all issues with Resolved status.

Discussion:

20.3.1.3.4 [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 20.3.1.3.2 [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 20.3.1.3.4 [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`.

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

[2015-05-18, Howard comments]

Updated proposed wording has been provided in N4366.

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

Proposed resolution:

Resolved by accepting N4366.