This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
experimental::observer_ptr
should have more constexprSection: 8.2.6 [fund.ts.v3::memory.observer.ptr.special] Status: New Submitter: Jonathan Wakely Opened: 2025-07-14 Last modified: 2025-07-14
Priority: Not Prioritized
View all issues with New status.
Discussion:
In the Library Fundamentals TS, the swap
overload, make_observer_ptr
function, and comparisons for observer_ptr
could be constexpr, but are not.
The member swap
is already constexpr in the TS, and the non-member swap
is constexpr in libc++ but not the comparisons. The proposed resolution has
been implemented and tested in libstdc++.
If we ever rebase the TS on a new C++ standard the comparisons should all be updated like so:
template <class W1, class W2> constexpr bool operator==(observer_ptr<W1> p1, observer_ptr<W2> p2);
Returns:p1.get() == p2.get()
.
bool operator!=(...);template <class W> constexpr bool operator==(observer_ptr<W> p, nullptr_t) noexcept;
bool operator==(...);Returns:not p
.
bool operator!=(...); bool operator!=(...);template <class W1, class W2> constexpr bool operator<=>(observer_ptr<W1> p1, observer_ptr<W2> p2);
Returns:, where
less<W3>compare_three_way()(p1.get(), p2.get())W3
is the composite pointer type (C++20 §7) ofW1*
andW2*
.
bool operator>(...); bool operator<=(...); bool operator>=(...);
Proposed resolution:
This wording is relative to N4939.
#include <memory> namespace std { namespace experimental::inline fundamentals_v3 { // 8.2, Non-owning (observer) pointers template <class W> class observer_ptr; // 8.2.6, observer_ptr specialized algorithms template <class W> constexpr void swap(observer_ptr<W>&, observer_ptr<W>&) noexcept; template <class W> constexpr observer_ptr<W> make_observer(W*) noexcept; // (in)equality operators template <class W1, class W2> constexpr bool operator==(observer_ptr<W1>, observer_ptr<W2>); template <class W1, class W2> constexpr bool operator!=(observer_ptr<W1>, observer_ptr<W2>); template <class W> constexpr bool operator==(observer_ptr<W>, nullptr_t) noexcept; template <class W> constexpr bool operator!=(observer_ptr<W>, nullptr_t) noexcept; template <class W> constexpr bool operator==(nullptr_t, observer_ptr<W>) noexcept; template <class W> constexpr bool operator!=(nullptr_t, observer_ptr<W>) noexcept; // ordering operators template <class W1, class W2> constexpr bool operator<(observer_ptr<W1>, observer_ptr<W2>); template <class W1, class W2> constexpr bool operator>(observer_ptr<W1>, observer_ptr<W2>); template <class W1, class W2> constexpr bool operator<=(observer_ptr<W1>, observer_ptr<W2>); template <class W1, class W2> constexpr bool operator>=(observer_ptr<W1>, observer_ptr<W2>); } // namespace experimental::inline fundamentals_v3 // 8.2.7, observer_ptr hash support template <class T> struct hash; template <class T> struct hash<experimental::observer_ptr<T>>; } // namespace std
template <class W> constexpr void swap(observer_ptr<W>& p1, observer_ptr<W>& p2) noexcept;
-2- Effects:p1.swap(p2)
.template <class W> constexpr observer_ptr<W> make_observer(W* p) noexcept;
-4- Returns:observer_ptr<W>{p}
.template <class W1, class W2> constexpr bool operator==(observer_ptr<W1> p1, observer_ptr<W2> p2);
-6- Returns:p1.get() == p2.get()
.template <class W1, class W2> constexpr bool operator!=(observer_ptr<W1> p1, observer_ptr<W2> p2);
-8- Returns:not (p1 == p2)
.template <class W> constexpr bool operator==(observer_ptr<W> p, nullptr_t) noexcept; template <class W> constexpr bool operator==(nullptr_t, observer_ptr<W> p) noexcept;
-10- Returns:not p
.template <class W> constexpr bool operator!=(observer_ptr<W> p, nullptr_t) noexcept; template <class W> constexpr bool operator!=(nullptr_t, observer_ptr<W> p) noexcept;
-12- Returns:(bool)p
.template <class W1, class W2> constexpr bool operator<(observer_ptr<W1> p1, observer_ptr<W2> p2);
-14- Returns:less<W3>()(p1.get(), p2.get())
, whereW3
is the composite pointer type (C++20 §7) ofW1*
andW2*
.template <class W1, class W2> constexpr bool operator>(observer_ptr<W1> p1, observer_ptr<W2> p2);
-16- Returns:p2 < p1
.template <class W1, class W2> constexpr bool operator<=(observer_ptr<W1> p1, observer_ptr<W2> p2);
-16- Returns:not p2 < p1
.template <class W1, class W2> constexpr bool operator>=(observer_ptr<W1> p1, observer_ptr<W2> p2);
-16- Returns:not p1 < p2
.