unique_ptr(pointer p)
for pointer deleter typesSection: 20.3.1.3.2 [unique.ptr.single.ctor] Status: Resolved Submitter: Howard Hinnant Opened: 2008-11-26 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [unique.ptr.single.ctor].
View all issues with Resolved status.
Discussion:
Addresses US 79
20.3.1.3.2 [unique.ptr.single.ctor]/5 no longer requires for D
not to be a pointer type. I believe this restriction was accidently removed
when we relaxed the completeness reuqirements on T
. The restriction
needs to be put back in. Otherwise we have a run time failure that could
have been caught at compile time:
{ unique_ptr<int, void(*)(void*)> p1(malloc(sizeof(int))); // should not compile } // p1.~unique_ptr() dereferences a null function pointer unique_ptr<int, void(*)(void*)> p2(malloc(sizeof(int)), free); // ok
[ Post Summit: ]
Recommend 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-07 Frankfurt: ]
We need to consider whether some requirements in the Requires paragraphs of [unique.ptr] should instead be Remarks.
Leave Open. Howard to provide wording, and possibly demonstrate how this can be implemented using enable_if.
[ 2009-07-27 Howard adds: ]
The two constructors to which this issue applies are not easily constrained with
enable_if
as they are not templated:unique_ptr(); explicit unique_ptr(pointer p);To "SFINAE" these constructors away would take heroic effort such as specializing the entire
unique_ptr
class template on pointer deleter types. There is insufficient motivation for such heroics. Here is the expected and reasonable implementation for these constructors:unique_ptr() : ptr_(pointer()) { static_assert(!is_pointer<deleter_type>::value, "unique_ptr constructed with null function pointer deleter"); } explicit unique_ptr(pointer p) : ptr_(p) { static_assert(!is_pointer<deleter_type>::value, "unique_ptr constructed with null function pointer deleter"); }I.e. just use
static_assert
to verify that the constructor is not instantiated with a function pointer for a deleter. The compiler will automatically take care of issuing a diagnostic if the deleter is a reference type (uninitialized reference error).In keeping with our discussions in Frankfurt, I'm moving this requirement on the implementation from the Requires paragraph to a Remarks paragraph.
[ 2009-08-17 Daniel adds: ]
It is insufficient to require a diagnostic. This doesn't imply an ill-formed program as of 3.17 [defns.diagnostic] (a typical alternative would be a compiler warning), but exactly that seems to be the intend. I suggest to use the following remark instead:
Remarks: The program shall be ill-formed if this constructor is instantiated when
D
is a pointer type or reference type.Via the general standard rules of 4.1 [intro.compliance] the "diagnostic required" is implied.
[ 2009-10 Santa Cruz: ]
Moved to Ready.
[ 2010-03-14 Howard adds: ]
We moved N3073 to the formal motions page in Pittsburgh which should obsolete this issue. I've moved this issue to NAD Editorial, solved by N3073.
Rationale:
Solved by N3073.
Proposed resolution:
Change the description of the default constructor in 20.3.1.3.2 [unique.ptr.single.ctor]:
unique_ptr();-1- Requires:
D
shall be default constructible, and that construction shall not throw an exception.D
shall not be a reference type or pointer type (diagnostic required)....
Remarks: The program shall be ill-formed if this constructor is instantiated when
D
is a pointer type or reference type.
Add after 20.3.1.3.2 [unique.ptr.single.ctor]/8:
unique_ptr(pointer p);...
Remarks: The program shall be ill-formed if this constructor is instantiated when
D
is a pointer type or reference type.