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.

4281. Inconsistency between value_or() and error_or() in std::expected

Section: 22.5.3.7 [optional.observe], 22.8.6.6 [expected.object.obs] Status: New Submitter: Hiroaki Ando Opened: 2025-06-27 Last modified: 2025-07-01

Priority: Not Prioritized

View other active issues in [optional.observe].

View all other issues in [optional.observe].

View all issues with New status.

Discussion:

In 22.8.6.6 [expected.object.obs]/19, the return value of value_or() is specified as follows:

Returns: has_value() ? **this : static_cast<T>(std::forward<U>(v)).
Meanwhile, the return value of error_or() is specified as follows (22.8.6.6 [expected.object.obs]/23):
Returns: std::forward<G>(e) if has_value() is true, error() otherwise.
Since these functions appear to be dual in nature, it would be preferable to maintain consistent notation.

Jonathan adds: The wording in expected::error_or is newer, having been added by P2505R5, and intentionally avoided a conditional expression (the problems with conditional expressions explained in P3177R0 don't actually affect these member functions, due to the non-const prvalue return type, but determining that there are no pessimized copies in value_or wouldn't be necessary if we didn't specify it with a conditional expression). The error_or wording also avoids using an explicit conversion when the Mandates: element requires implicit conversion to work anyway. We might want to rephrase the value_or wording to match error_or, or possibly make value_or and error_or even more explicit, specifying them in terms of if-else: :

Effects: Equivalent to:

if (has_value())
  return **this;
else
  return std::forward<U>(v);

Proposed resolution: