1. Motivation
Today,
provides a
member function that can be used to check whether the instance holds a value or an error.
There is also an implicit conversion operator to
that can be used for the same purpose.
These two existing mechanisms follow several other facilities in the language, including
.
While
provides only the
member function as its primary state-checking mechanism,
serves a fundamentally different purpose.
Unlike
, which represents either a value or nothing,
represents either a value or an error.
This semantic difference warrants distinct interface considerations.
Adding
creates symmetry in the API that better reflects the dual-state nature of
and provides more readable, self-documenting code when the focus is on error handling rather than value presence.
1.1. Sample usecase
Consider the following examples (assuming
is of type
):
Without this proposal | With this proposal |
|
|
|
|
1.2. Impact on the standard
This change is entirely based on library extensions and does not require any language features beyond what is available in C++ 23.
1.3. Other languages
It might be unexpected to not have a
method in
, especially when moving from other languages that have similar constructs.
The proposed approach is consistent with similar facilities in some other programming languages:
-
Rust provides both
andis_ok ()
methods on itsis_err ()
type.Result -
D provides both
andhasValue
properties in itshasError
package.expected -
Haskell provides
andisRight
in itsisLeft
type.Either
These implementations acknowledge the dual-state nature of error-handling types by offering explicit methods for checking both states, rather than relying solely on negation of a value-checking method.
2. Proposed Wording
In 22.8.6.1 [expected.object.general] add:
constexpr bool has_value () const noexcept ; constexpr bool has_error () const noexcept ; constexpr const T & value () const & ;
In 22.8.6.6 [expected.object.obs] add after ❡7:
constexpr bool has_error () const noexcept ; Returns : ! has_val . Remarks : Equivalent to ! has_value ()
In 22.8.7.1 [expected.void.general] add:
constexpr bool has_value () const noexcept ; constexpr bool has_error () const noexcept ; constexpr void operator * () const noexcept ;
In 22.8.7.6 [expected.void.obs] add after ❡1:
constexpr bool has_error () const noexcept ; Returns : ! has_val . Remarks : Equivalent to ! has_value ()