次期C++2b(C++23)標準ライブラリに追加されるstd::expected<T, E>
クラステンプレートについてメモ。
- 従来C++例外機構(throw文+try/catch構文)に代わり、関数の演算結果(
T
型)またはエラー情報(E
型)を “値” として返す(return)ための部品。 - C++17
std::optional<T>
型の無効値(std::nullopt
)表現に代わり、具体的なエラー情報(E
型)を保持可能に拡張された型。*1 - 新しい標準ヘッダ<expected>
- クラステンプレート
expected<T, E>
、補助型unexpected<E>
*2、タグunexpect
、例外型bad_expected_access<E>
- クラステンプレート
expected<T, E>
== 結果T
とエラーunexpected<E>
の直和型*3- constexpr文脈でも利用可能
expected<void, E>
特殊化 == エラーのみを保持するstd::optional
同様に参照型は未サポート
expected<T, E>
型への代入/直接構築:- 結果/
T
へ変換可能な型:r = t;
または{std::in_place, t};
*4 - エラー/
E
へ変換可能な型:r = std::unexpected(e);
または{std::unexpect, e};
- 結果/
- 保持値アクセス:
expected
モナディック(monadic)操作はC++2bには間に合わず*7、C++2c(C++26)向け提案文書 P2505 にて継続検討中。- C++2b標準ライブラリ
optional
モナディック操作(and_then
,or_else
など)は P0789R8 が採択済み。 - 2022-11-29追記:2022年11月会合で提案文書P2505R5が採択され、C++2b標準ライブラリに
expected
モナディック操作群が追加される。
- C++2b標準ライブラリ
Boost.Outcomeライブラリとの比較:
- Boost.Outcome, Review of Error Handling Frameworks
- Boost.Outcome, Frequently asked questions, How far away from the proposed
std::expected<T, E>
is Outcome'schecked<T, E>
? - (PDF) P0762R0 Concerns about expected<T, E> from the Boost.Outcome peer review
関連URL
- P0323R12 std::expected
- エラー値と正常値を表す汎用的な型:expected - Faith and Brave - C++で遊ぼう
- [C++]WG21月次提案文書を眺める(2021年04月) - 地面を見下ろす少年の足蹴にされる私
- https://github.com/TartanLlama/expected
*1:std::optional<T> ≒ std::expected<T, std::nullopt_t>
*2:C++20現在、識別子 unexpected はZombie nameとして予約されおり、expected<T, E> 導入に伴ってC++2bで蘇生(?)された初のケース。C++的ゾンビのお名前 参照。
*3:無効値 nullopt でデフォルト構築される std::optional<T> とは異なり、エラー情報を明示的に保持する std::expected<T, E> ではデフォルト構築後は結果値 T{} を保持している。
*4:https://cpprefjp.github.io/reference/utility/in_place_t.html
*5:if文の条件式などに expected<T, E> 型の値を記述することで、結果を保持しているか否かを判定可能(→id:yohhoy:20121110)
*6:提案文書P0323R12 §3.14: "Using the indirection operator for an object that does not contain a value is undefined behavior. This behavior offers maximum runtime performance."
*7:https://github.com/cplusplus/papers/issues/1161#issuecomment-1027125553