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:

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

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