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.

### 950. `unique_ptr` converting ctor shouldn't accept array form

Section: 20.3.1.3.2 [unique.ptr.single.ctor] Status: Resolved Submitter: Howard Hinnant Opened: 2009-01-07 Last modified: 2016-01-28

Priority: Not Prioritized

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

View all issues with Resolved status.

Discussion:

`unique_ptr`'s of array type should not convert to `unique_ptr`'s which do not have an array type.

>     struct Deleter
>     {
>        void operator()(void*) {}
>     };

>     int main()
>     {
>        unique_ptr<int[], Deleter> s;
>        unique_ptr<int, Deleter> s2(std::move(s));  // should not compile
>     }

[ Post Summit: ]

> Walter: Does the "diagnostic required" apply to both arms of the "and"?

> Tom Plum: suggest to break into several sentences

> Walter: suggest "comma" before the "and" in both places

> Recommend Review.

[ Batavia (2009-05): ]

> The post-Summit comments have been applied to the proposed resolution. We now agree with the proposed resolution. Move to Tentatively Ready.

[ 2009-07 Frankfurt ]

> Moved from Tentatively Ready to Open only because the wording needs to be improved for `enable_if` type constraining, possibly following Robert's formula.

[ 2009-08-01 Howard updates wording and sets to Review. ]

[ 2009-10 Santa Cruz: ]

> Move to Ready.

[ 2010-02-27 Pete Opens: ]

> The proposed replacement text doesn't make sense.

> > If `D` is a reference type, then `E` shall be the same type as `D`, else this constructor shall not participate in overload resolution.

> This imposes two requirements. 1. If `D` is a reference type, `E` has to be `D`. 2. If `D` is not a reference type, the constructor shall not participate in overload resolution. If the latter apples, the language in the preceding paragraph that this constructor shall not throw an exception if `D` is not a reference type is superfluous. I suspect that's not the intention, but I can't parse this text any other way.

> > `U` shall not be an array type, else this constructor shall not participate in overload resolution.

> I don't know what this means.

[ 2010-02-27 Peter adds: ]

> I think that the intent is (proposed text):

> > Remarks: this constructor shall only participate in overload resolution if:

> > - `unique_ptr<U, E>::pointer` is implicitly convertible to `pointer`,
> > - `U` is not an array type, and
> > - if `D` is a reference type, `E` is the same type as `D`.

[ 2010-02-28 Howard adds: ]

> I like Peter's proposal. Here is a tweak of it made after looking at my implementation. I believe this fixes a further defect not addressed by the current proposed wording:

> > Remarks: this constructor shall only participate in overload resolution if:

> > - `unique_ptr<U, E>::pointer` is implicitly convertible to `pointer`, and
> > - `U` is not an array type, and
> > - if `D` is a reference type, `E` is the same type as `D`, else `E` shall be implicitly convertible to `D`.

[ 2010 Pittsburgh: Moved to NAD Editorial. Rationale added below. ]

Rationale:

Solved by N3073.

Proposed resolution:

Change 20.3.1.3.2 [unique.ptr.single.ctor]:

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

> > -20- Requires: If `D` is not a reference type, construction of the deleter `D` from an rvalue of type `E` shall be well formed and shall not throw an exception. If `D` is a reference type, then `E` shall be the same type as `D` (diagnostic required). `unique_ptr<U, E>::pointer` shall be implicitly convertible to `pointer`. [Note: These requirements imply that `T` and `U` are complete types. — end note]

> > Remarks: If `D` is a reference type, then `E` shall be the same type as `D`, else this constructor shall not participate in overload resolution. `unique_ptr<U, E>::pointer` shall be implicitly convertible to `pointer`, else this constructor shall not participate in overload resolution. `U` shall not be an array type, else this constructor shall not participate in overload resolution. [Note: These requirements imply that `T` and `U` are complete types. — end note]

Change 20.3.1.3.4 [unique.ptr.single.asgn]:

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

> > -6- Requires: Assignment of the deleter `D` from an rvalue `D` shall not throw an exception. `unique_ptr<U, E>::pointer` shall be implicitly convertible to `pointer`. [Note: These requirements imply that `T` and `U` are complete types. — end note]

> > Remarks: `unique_ptr<U, E>::pointer` shall be implicitly convertible to `pointer`, else this operator shall not participate in overload resolution. `U` shall not be an array type, else this operator shall not participate in overload resolution. [Note: These requirements imply that `T` and `U` are complete types. — end note]