unique_ptr
converting ctor shouldn't accept array formSection: 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, thenE
shall be the same type asD
, else this constructor shall not participate in overload resolution.This imposes two requirements. 1. If
D
is a reference type,E
has to beD
. 2. IfD
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 ifD
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 topointer
,U
is not an array type, and- if
D
is a reference type,E
is the same type asD
.
[ 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 topointer
, andU
is not an array type, and- if
D
is a reference type,E
is the same type asD
, elseE
shall be implicitly convertible toD
.
[ 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 deleterD
from an rvalue of typeE
shall be well formed and shall not throw an exception.IfD
is a reference type, thenE
shall be the same type asD
(diagnostic required).unique_ptr<U, E>::pointer
shall be implicitly convertible topointer
. [Note: These requirements imply thatT
andU
are complete types. — end note]Remarks: If
D
is a reference type, thenE
shall be the same type asD
, else this constructor shall not participate in overload resolution.unique_ptr<U, E>::pointer
shall be implicitly convertible topointer
, 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 thatT
andU
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 rvalueD
shall not throw an exception.unique_ptr<U, E>::pointer
shall be implicitly convertible topointer
. [Note: These requirements imply thatT
andU
are complete types. — end note]Remarks:
unique_ptr<U, E>::pointer
shall be implicitly convertible topointer
, 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 thatT
andU
are complete types. — end note]