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.

### 2801. Default-constructibility of `unique_ptr`

Section: 20.3.1.3.2 [unique.ptr.single.ctor] Status: C++17 Submitter: United States Opened: 2016-11-09 Last modified: 2017-07-30

Priority: 2

View all other issues in [unique.ptr.single.ctor].

View all issues with C++17 status.

Discussion:

Addresses US 122

`unique_ptr` should not satisfy `is_constructible_v<unique_ptr<T, D>>` unless `D` is `DefaultConstructible` and not a pointer type. This is important for interactions with `pair`, `tuple`, and `variant` constructors that rely on the `is_default_constructible` trait.

Suggested resolution:

Add a Remarks: clause to constrain the default constructor to not exist unless the Requires clause is satisfied.

[Issues Telecon 16-Dec-2016]

Priority 2; Howard and Ville to provide wording.

[2016-12-24: Howard and Ville provided wording.]

[2017-03-02, Kona, STL comments and tweaks the wording]

LWG discussed this issue, and we liked it, but we wanted to tweak the PR. I ran this past Ville (who drafted the PR with Howard), and he was in favor of tweaking this.

[Kona 2017-03-02]

Accepted as Immediate to resolve NB comment.

Proposed resolution:

1. Modify the synopsis in 20.3.1.3 [unique.ptr.single] as follows:

   >     […]
   >     constexpr unique_ptr(nullptr_t) noexcept;
   >         : unique_ptr() { }
   >     […]

2. Modify 20.3.1.3.2 [unique.ptr.single.ctor] as follows:

   >     constexpr unique_ptr() noexcept;
   >     constexpr unique_ptr(nullptr_t) noexcept;

   > > -1- Requires: `D` shall satisfy the requirements of `DefaultConstructible` (Table 22), and that construction shall not throw an exception.

   > > -2- Effects: Constructs a `unique_ptr` object that owns nothing, value-initializing the stored pointer and the stored deleter.

   > > -3- Postconditions: `get() == nullptr`. `get_deleter()` returns a reference to the stored deleter.

   > > -4- Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument `D`, the program is ill-formed. If `is_pointer_v<deleter_type>` is `true` or `is_default_constructible_v<deleter_type>` is `false`, this constructor shall not participate in overload resolution.

   >     explicit unique_ptr(pointer p) noexcept;

   > > […]

   > > -8- Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument `D`, the program is ill-formed. If `is_pointer_v<deleter_type>` is `true` or `is_default_constructible_v<deleter_type>` is `false`, this constructor shall not participate in overload resolution.

3. Modify the synopsis in 20.3.1.4 [unique.ptr.runtime] as follows:

   >     […]
   >     constexpr unique_ptr(nullptr_t) noexcept; : unique_ptr() { }
   >     […]

4. Modify 20.3.1.4.2 [unique.ptr.runtime.ctor] as follows:

   >     template <class U> explicit unique_ptr(U p) noexcept;

   > > This constructor behaves the same as the constructor that takes a pointer parameter in the primary template except that the following constraints are added for it to participate in overload resolution

   > > - `U` is the same type as `pointer`, or

   > > - `pointer` is the same type as `element_type*`, `U` is a pointer type `V*`, and `V(*)[]` is convertible to `element_type(*)[]`.

   >     template <class U> unique_ptr(U p, see below d) noexcept;
   >     template <class U> unique_ptr(U p, see below d) noexcept;

   > > 1 These constructors behave the same as the constructors that take a pointer parameter in the primary template except that they shall not participate in overload resolution unless either