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_iftype 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
Dis a reference type, thenEshall be the same type asD, else this constructor shall not participate in overload resolution.This imposes two requirements. 1. If
Dis a reference type,Ehas to beD. 2. IfDis 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 ifDis not a reference type is superfluous. I suspect that's not the intention, but I can't parse this text any other way.
Ushall 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>::pointeris implicitly convertible topointer,Uis not an array type, and- if
Dis a reference type,Eis 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>::pointeris implicitly convertible topointer, andUis not an array type, and- if
Dis a reference type,Eis the same type asD, elseEshall 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
Dis not a reference type, construction of the deleterDfrom an rvalue of typeEshall be well formed and shall not throw an exception.IfDis a reference type, thenEshall be the same type asD(diagnostic required).unique_ptr<U, E>::pointershall be implicitly convertible topointer. [Note: These requirements imply thatTandUare complete types. — end note]Remarks: If
Dis a reference type, thenEshall be the same type asD, else this constructor shall not participate in overload resolution.unique_ptr<U, E>::pointershall be implicitly convertible topointer, else this constructor shall not participate in overload resolution.Ushall not be an array type, else this constructor shall not participate in overload resolution. [Note: These requirements imply thatTandUare 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
Dfrom an rvalueDshall not throw an exception.unique_ptr<U, E>::pointershall be implicitly convertible topointer. [Note: These requirements imply thatTandUare complete types. — end note]Remarks:
unique_ptr<U, E>::pointershall be implicitly convertible topointer, else this operator shall not participate in overload resolution.Ushall not be an array type, else this operator shall not participate in overload resolution. [Note: These requirements imply thatTandUare complete types. — end note]