This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.
Section: 20.3.1.3.2 [unique.ptr.single.ctor] Status: C++17 Submitter: United States Opened: 2017-02-03 Last modified: 2017-07-30
Priority: Not Prioritized
View all other issues in [unique.ptr.single.ctor].
View all issues with C++17 status.
Discussion:
Addresses US 123is_constructible_v<unique_ptr<P, D>, P, D const &> should be false when D is not copy constructible, and similarly for D&& when D is not move constructible. This could be achieved by the traditional 'does not participate in overload resolution' wording, or similar.
Proposed change: Add a Remarks: clause to constrain the appropriate constructors.
[2017-02-28, Jonathan comments and provides concrete wording]
As well as addressing the NB comment, this attempts to make some further improvements to the current wording, which is a little strange.
It incorrectly uses "d
" to mean the constructor argument that initializes the parameter d
, and unnecessarily explains how overload resolution works for lvalues and rvalues.
It refers to the copy/move constructor of D
, but the constructor that is selected to perform the initialization may not be a copy/move constructor (e.g. initializing a deleter object from an rvalue might use a copy constructor if there is no move constructor).
The condition "d
shall be reference compatible with one of the constructors" is bogus: reference compatible is a property of two types, not a value and a constructor, and again is trying to talk about the argument not the parameter.
Note that we could replace the "see below" in the signatures and paragraphs 9, 10 and 11 by declaring the constructors as:
unique_ptr(pointer p, const D& d) noexcept; unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept;
I think this produces the same signatures in all cases. I haven't proposed that here, it could be changed separately if desired.
[Kona 2017-02-27]
Accepted as Immediate to resolve NB comment.
Proposed resolution:
Modify [unique.ptr.single.ctor] paragraphs 9-11 as shown:
unique_ptr(pointer p, see below d1) noexcept; unique_ptr(pointer p, see below d2) noexcept;-9- The signature of these constructors depends upon whether
D
is a reference type. IfD
is a non-reference typeA
, then the signatures areunique_ptr(pointer p, const A& d) noexcept; unique_ptr(pointer p, A&& d) noexcept;
-10- If
D
is an lvalue reference typeA&
, then the signatures are:unique_ptr(pointer p, A& d) noexcept; unique_ptr(pointer p, A&& d) = delete;
-11- If
D
is an lvalue reference typeconst A&
, then the signatures are:unique_ptr(pointer p, const A& d) noexcept; unique_ptr(pointer p, const A&& d) = delete;
Remove paragraph 12 entirely:
-12- Requires:
IfD
is not an lvalue reference type then
Ifd
is an lvalue or const rvalue then the first constructor of this pair will be selected.D
shall satisfy the requirements ofCopyConstructible
(Table 24), and the copy constructor ofD
shall not throw an exception. Thisunique_ptr
will hold a copy ofd
.Otherwise,d
is a non-const rvalue and the second constructor of this pair will be selected.D
shall satisfy the requirements ofMoveConstructible
(Table 23), and the move constructor ofD
shall not throw an exception. Thisunique_ptr
will hold a value move constructed fromd
.OtherwiseD
is an lvalue reference type.d
shall be reference-compatible with one of the constructors. Ifd
is an rvalue, it will bind to the second constructor of this pair and the program is ill-formed. [Note: The diagnostic could be implemented using a static_assert which assures thatD
is not a reference type. — end note] Elsed
is an lvalue and will bind to the first constructor of this pair. The type whichD
references need not beCopyConstructible
norMoveConstructible
. Thisunique_ptr
will hold aD
which refers to the lvalued
. [Note:D
may not be an rvalue reference type. — end note]
Modify paragraph 13 as shown:
-13- Effects: Constructs a
unique_ptr
object which ownsp
, initializing the stored pointer withp
and initializing the deleteras described abovefromstd::forward<decltype(d)>(d)
.
Add a new paragraph after paragraph 14 (Postconditions):
-?- Remarks: These constructors shall not participate in overload resolution unless
is_constructible_v<D, decltype(d)>
istrue
.