3426. operator<=>(const unique_ptr<T, D>&, nullptr_t) can't get no satisfaction

Section: 20.3.1.6 [unique.ptr.special] Status: C++23 Submitter: Jonathan Wakely Opened: 2020-04-09 Last modified: 2023-11-22

Priority: 0

View all other issues in [unique.ptr.special].

View all issues with C++23 status.

Discussion:

The constraint for operator<=>(const unique_ptr<T, D>&, nullptr_t) cannot be satisfied, because std::three_way_comparable<nullptr_t> is false, because nullptr <=> nullptr is ill-formed.

We can make it work as intended by comparing x.get() to pointer(nullptr) instead of to nullptr directly.

[2020-04-14; Replacing the functional cast by a static_cast as result of reflector discussion]

[2020-04-18 Issue Prioritization]

Status set to Tentatively Ready after seven 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.2.2 [memory.syn] as indicated:

    […]
    template<class T, class D>
      bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
    template<class T, class D>
      requires three_way_comparable_with<typename unique_ptr<T, D>::pointer, nullptr_t>
      compare_three_way_result_t<typename unique_ptr<T, D>::pointer, nullptr_t>
        operator<=>(const unique_ptr<T, D>& x, nullptr_t);
    […]
    
  2. Modify 20.3.1.6 [unique.ptr.special] as indicated:

    template<class T, class D>
      requires three_way_comparable_with<typename unique_ptr<T, D>::pointer, nullptr_t>
      compare_three_way_result_t<typename unique_ptr<T, D>::pointer, nullptr_t>
        operator<=>(const unique_ptr<T, D>& x, nullptr_t);
    

    -18- Returns: compare_three_way()(x.get(), static_cast<typename unique_ptr<T, D>::pointer>(nullptr)).