[P0323R11] (will be update to R12 once that revision published) introduced class template 
However, even thoughstd :: expected < int , std :: errc > svtoi ( std :: string_view sv ) { int value { 0 }; auto [ ptr , ec ] = std :: from_chars ( sv . begin (), sv . end (), value ); if ( ec == std :: errc {}) { return value ; } return std :: unexpected ( ec ); } 
std :: unexpected < E > E value () std :: expected < T ,  E > error () [P0323R11] is adopted for C++23 at the Feburary 2022 WG21 Plenary, so this proposal also targets C++23 to fix this.
1. Revision History
1.1. R0
Initial revision.2. Motivation
Consistency among library vocabulary types is important and makes user interaction intuitive, and since 
We can have a comparison on the various member access method of the 
| Member | Return Type |  |  |  |  | 
| (Normal) Value |  |  |  | N/A | N/A | 
| Unexpected Outcome (Error) | () | N/A |  |  |  | 
We can see that the only outlier in this table is 
Provide 
- 
     Consistency: Both consistent with std :: expected < T , E > std :: bad_expected_access < E > error () value () 
- 
     Generic: Same name means more generic code is allowed. For example, generic code can do e . error () std :: expected < T , E > std :: unexpected < E > std :: bad_expected_access < E > std :: status_code std :: error 
- 
     Safety & Inituitive: Other value () std :: unexpected < E > value () 
Side note: you can even smell the inconsistency when many of the wording of equality operator between 
3. Design
3.1. Alternative Design
This section lists the alternative choices and possible arguments against this proposal that has been considered.3.1.1. But we are already badly inconsistent!
Some may argue that the intensive use ofvalue () I would argue that most use of 
3.1.2. Conversion operator
The other standard library wrapper type,std :: reference_wrapper < T > T & std :: unexpected < E > E A similar choice had been facing the designer of 
We do not think that providing an implicit conversion to T would be a good choice. First, it would require different way of checking for the empty state; and second, such implicit conversion is not perfect and still requires other means of accessing the contained value if we want to call a member function on it.
I think that this reasoning also applies here. Even if it is implicit, conversion operator is not perfect (call member functions), and we still need 
3.1.3. No member accessor
The above discussion leads to the consideration: sincestd :: unexpected < E > return  std :: unexpected ( some_error ); This is an interesting point. Also, one of [P0323R11]'s referenced implementation [viboes-expected] does this: its 
3.2. Target Vehicle
This proposal targets C++23. I’m aware that the design freeze deadline of C++23 is already passed, but I think this can be classified as an improvement/fix over the defect instd :: expected < T ,  E > 3.3. Feature Test Macro
As long as the proposal lands in C++23, I don’t think there is a need to change any feature test macro. However, if L(E)WG feels there is a need, then I suggest bumping__cpp_lib_expected 202202L 4. Implementation & Usage Experience
The referenced implementation of [P0323R11] all implement the interface of original proposal (except [viboes-expected] mentioned above). This section thus investigated several similar implementations.
4.1. Outcome v2
[outcome-v2] is a popular library invested in a set of tools for reporting and handling function failures in contexts where directly using C++ exception handling is unsuitable. It is both provided as Boost.Outcome and the standalone GitHub repository, and also having an experimental branch that is the basis of [P1095R0] and [P1028R3]std :: status_code result < T ,  E ,  Policy > outcome < T ,  EC ,  EP ,  Policy > std :: expected < T ,  E > outcome EC EP result < T ,  E > std :: expected < T ,  E > outcome :: result < T ,  E > One of the main design difference is that 
| Member | Return Type |  |  |  |  | 
| (Normal) Value |  |  |  |  | N/A | 
| Unexpected Outcome (Error) | (orand) |  |  | N/A |  | 
We can see that Outcome v2 is pretty consistent in member accessor, and especially its 
4.2. Boost.LEAF
Lightweight Error Augmentation Framework (LEAF), or [Boost.LEAF], is a lightweight error handling library for C++11. It is intended to be an improved version of Outcome, by eliminating branchy code and remove error type fromresult < T ,  E > LEAF is designed with a strong bias towards the common use case where callers of functions which may fail check for success and forward errors up the call stack but do not handle them. In this case, only a trivial success-or-failure discriminant is transported. Actual error objects are communicated directly to the error handling scope, skipping the intermediate check-only frames altogether.
The main type for LEAF is 
| Member | Return Type |  |  | 
| (Normal) Value |  |  | N/A | 
| Unexpected Outcome (Error) |  |  |  | 
leaf :: error_id value () std :: error_code leaf :: error_id 5. Wording
The wording below is based on [N4901] plus the editorial PR of P0323R12. This will be rebased onto post-Feburary Working Draft in the next revision, with hopefully no change of section name.
5.1. 20.9.3.2 Class template unexpected 
   5.1.1. 20.9.3.2.1 General [expected.un.object.general]
namespace std { template < class E > class unexpected { public : constexpr unexpected ( const unexpected & ) = default ; constexpr unexpected ( unexpected && ) = default ; template < class ... Args > constexpr explicit unexpected ( in_place_t , Args && ...); template < class U , class ... Args > constexpr explicit unexpected ( in_place_t , initializer_list < U > , Args && ...); template < class Err = E > constexpr explicit unexpected ( Err && ); constexpr unexpected & operator = ( const unexpected & ) = default ; constexpr unexpected & operator = ( unexpected && ) = default ; constexpr const E & value error () const & noexcept ; constexpr E & value error () & noexcept ; constexpr const E && value error () const && noexcept ; constexpr E && value error () && noexcept ; constexpr void swap ( unexpected & other ) noexcept ( see below ); template < class E2 > friend constexpr bool operator == ( const unexpected & , const unexpected < E2 >& ); friend constexpr void swap ( unexpected & x , unexpected & y ) noexcept ( noexcept ( x . swap ( y ))); private : E val ; // exposition only }; template < class E > unexpected ( E ) -> unexpected < E > ; } 
5.1.2. 20.9.3.2.3 Observers [expected.un.obs]
constexpr const E & value error () const & noexcept ; constexpr E & value error () & noexcept ; 
Returns: 
constexpr E && value error () && noexcept ; constexpr const E && value error () const && noexcept ; 
Returns: 
5.1.3. 20.9.3.2.5 Equality operator [expected.un.eq]
template < class E2 > friend constexpr bool operator == ( const unexpected & x , const unexpected < E2 >& y ); 
Mandates: The expression 
Returns: 
5.2. 20.9.6 Class template expected 
   5.2.1. 20.9.6.2 Constructors [expected.object.ctor]
template < class G > constexpr explicit ( ! is_convertible_v < const G & , E > ) expected ( const unexpected < G >& e ); template < class G > constexpr explicit ( ! is_convertible_v < G , E > ) expected ( unexpected < G >&& e ); 
Let 
Constraints: true.
Effects: Direct-non-list-initializes 
Postconditions: false.
Throws: Any exception thrown by the initialization of 
5.2.2. 20.9.6.4 Assignment [expected.object.assign]
template < class G > constexpr expected & operator = ( const unexpected < G >& e ); template < class G > constexpr expected & operator = ( unexpected < G >&& e ); 
Let 
Constraints:
- 
     is_constructible_v < E , GF > true; and
- 
     is_assignable_v < E & , GF > true; and
- 
     is_nothrow_constructible_v < E , GF > || is_nothrow_move_constructible_v < T > || is_nothrow_move_constructible_v < E > true.
Effects:
- 
     If has_value () true, equivalent to:reinit - expected ( unex , val , std :: forward < GF > ( e . value error ())); has_val = false; 
- 
     Otherwise, equivalent to: unex = std :: forward < GF > ( e . value error ()); 
Returns: 
5.2.3. 20.9.6.7 Equality operators [expected.object.eq]
template < class E2 > friend constexpr bool operator == ( const expected & x , const unexpected < E2 >& e ); 
Mandates: The expression 
Returns: 
5.3. 20.9.7 Partial specialization of expected void 
   5.3.1. 20.9.7.2 Constructors [expected.void.ctor]
template < class G > constexpr explicit ( ! is_convertible_v < const G & , E > ) expected ( const unexpected < G >& e ); template < class G > constexpr explicit ( ! is_convertible_v < G , E > ) expected ( unexpected < G >&& e ); 
Let 
Constraints: true.
Effects: Direct-non-list-initializes 
Postconditions: false.
Throws: Any exception thrown by the initialization of 
5.3.2. 20.9.7.4 Assignment [expected.void.assign]
template < class G > constexpr expected & operator = ( const unexpected < G >& e ); template < class G > constexpr expected & operator = ( unexpected < G >&& e ); 
Let 
Constraints: true and true.
Effects:
- 
     If has_value () true, equivalent to:construct_at ( addressof ( unex ), std :: forward < GF > ( e . value error ())); has_val = false; 
- 
     Otherwise, equivalent to: unex = std :: forward < GF > ( e . value error ()); 
Returns: 
5.3.3. 20.9.7.7 Equality operators [expected.void.eq]
template < class E2 > constexpr bool operator == ( const expected & x , const unexpected < E2 >& e ); 
Mandates: The expression 
Returns: