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.

### 3427. `operator<=>(const shared_ptr<T>&, nullptr_t)` definition ill-formed

Section: 20.3.2.2.8 [util.smartptr.shared.cmp] Status: WP Submitter: Daniel Krügler Opened: 2020-04-11 Last modified: 2020-11-09

Priority: 0

View all other issues in [util.smartptr.shared.cmp].

View all issues with WP status.

Discussion:

This is similar to LWG 3426: This time the definition of `operator<=>(const shared_ptr<T>&, nullptr_t)` is ill-formed, whose effects are essentially specified as calling:

>     compare_three_way()(a.get(), nullptr)

This call will be ill-formed by constraint-violation, because both `nullptr <=> nullptr` as well as `((T*) 0) <=> nullptr` are ill-formed.

As a short-term solution we can make it work as intended — equivalent to LWG 3426 — by comparing `a.get()` to `(element_type*) nullptr` instead of to `nullptr` directly.

As a long-term solution we should at least consider to deprecate the mixed relational operators as well as the mixed three-way comparison operator of all our smart-pointers with `std::nullptr_t` since the core language has eliminated relational comparisons of pointers with `std::nullptr_t` with N3624 four years after they had been originally accepted by CWG 879. Consequently, for C++20, the mixed three-way comparison between pointers and `nullptr` is not supported either. For this long-term solution I'm suggesting to handle this via a proposal.

[2020-05-16 Reflector discussions]

Status to Tentatively Ready and priority to 0 after five positive votes on the reflector.

[2020-11-09 Approved In November virtual meeting. Status changed: Tentatively Ready → WP.]

Proposed resolution:

This wording is relative to N4861.

1. Modify 20.3.2.2.8 [util.smartptr.shared.cmp] as indicated:

   >     template<class T>
   >       strong_ordering operator<=>(const shared_ptr<T>& a, nullptr_t) noexcept;

   > > -5- Returns: `compare_three_way()(a.get(), static_cast<typename shared_ptr<T>::element_type*>(nullptr))`.