This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

### 2762. `unique_ptr operator*()` should be `noexcept`

Section: 20.3.1.3.5 [unique.ptr.single.observers] Status: WP Submitter: Ville Voutilainen Opened: 2016-08-04 Last modified: 2021-10-14

Priority: 3

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

View all issues with WP status.

Discussion:

See LWG 2337. Since we aren't removing `noexcept` from `shared_ptr`'s `operator*`, we should consider adding `noexcept` to `unique_ptr`'s `operator*`.

[2016-08 — Chicago]

Thurs PM: P3, and status to 'LEWG'

[2016-08-05 Chicago]

Ville provides an initial proposed wording.

[LEWG Kona 2017]

->Open: Believe these should be `noexcept` for consistency. We like these. We agree with the proposed resolution. `operator->()` already has `noexcept`.

Also adds `optional::operator*`

Alisdair points out that fancy pointers might intentionally throw from `operator*`, and we don't want to prohibit that.

Go forward with conditional `noexcept(noexcept(*decltype()))`.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4606.

> > [Drafting note: since this issue is all about consistency, `optional`'s pointer-like operators are additionally included.]

> 1. In 20.3.1.3 [unique.ptr.single] synopsis, edit as follows:

>    >     add_lvalue_reference_t<T> operator*() const noexcept;

> 2. Before 20.3.1.3.5 [unique.ptr.single.observers]/1, edit as follows:

>    >     add_lvalue_reference_t<T> operator*() const noexcept;

> 3. In 22.5.3 [optional.optional] synopsis, edit as follows:

>    >     constexpr T const *operator->() const noexcept;
>    >     constexpr T *operator->() noexcept;
>    >     constexpr T const &operator*() const & noexcept;
>    >     constexpr T &operator*() & noexcept;
>    >     constexpr T &&operator*() && noexcept;
>    >     constexpr const T &&operator*() const && noexcept;

> 4. Before [optional.object.observe]/1, edit as follows:

>    >     constexpr T const* operator->() const noexcept;
>    >     constexpr T* operator->() noexcept;

> 5. Before [optional.object.observe]/5, edit as follows:

>    >     constexpr T const& operator*() const & noexcept;
>    >     constexpr T& operator*() & noexcept;

> 6. Before [optional.object.observe]/9, edit as follows:

>    >     constexpr T&& operator*() && noexcept;
>    >     constexpr const T&& operator*() const && noexcept;

[2021-06-19 Tim updates wording]

[2021-06-23; Reflector poll]

Set status to Tentatively Ready after seven votes in favour during reflector poll.

[2021-10-14 Approved at October 2021 virtual plenary. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4892.

> [Drafting note: since this issue is all about consistency, `optional`'s pointer-like operators are additionally included.]

1. Edit 20.3.1.3.1 [unique.ptr.single.general], class template `unique_ptr` synopsis, as indicated:

   >     namespace std {
   >       template<class T, class D = default_delete<T>> class unique_ptr {
   >       public:
   >         […]

   >         // 20.3.1.3.5 [unique.ptr.single.observers], observers
   >         add_lvalue_reference_t<T> operator*() const noexcept(see below);
   >         […]
   >       };
   >     }

2. Edit 20.3.1.3.5 [unique.ptr.single.observers] as indicated:

   >     add_lvalue_reference_t<T> operator*() const noexcept(noexcept(*declval<pointer>()));

   > > -1- Preconditions: `get() != nullptr`.

   > > -2- Returns: `*get()`.

3. Edit 22.5.3.1 [optional.optional.general], class template `optional` synopsis, as indicated:

   >     namespace std {
   >       template<class T>
   >       class optional {
   >       public:
   >         […]

   >         // 22.5.3.6 [optional.observe], observers
   >         constexpr const T* operator->() const noexcept;
   >         constexpr T* operator->() noexcept;
   >         constexpr const T& operator*() const & noexcept;
   >         constexpr T& operator*() & noexcept;
   >         constexpr T&& operator*() && noexcept;
   >         constexpr const T&& operator*() const && noexcept;

   >         […]
   >       };
   >     }

4. Edit 22.5.3.6 [optional.observe] as indicated:

   >     constexpr const T* operator->() const noexcept;
   >     constexpr T* operator->() noexcept;

   > > -1- Preconditions: `*this` contains a value.

   > > -2- Returns: `val`.

   > > -3- Throws: Nothing.

   > > -4- Remarks: These functions are constexpr functions.

   >     constexpr const T& operator*() const & noexcept;
   >     constexpr T& operator*() & noexcept;

   > > -5- Preconditions: `*this` contains a value.

   > > -6- Returns: `*val`.

   > > -7- Throws: Nothing.

   > > -8- Remarks: These functions are constexpr functions.

   >     constexpr T&& operator*() && noexcept;
   >     constexpr const T&& operator*() const && noexcept;

   > > -9- Preconditions: `*this` contains a value.

   > > -10- Effects: Equivalent to: `return std::move(*val);`