std::expected
From cppreference.com
| ヘッダ <expected> で定義 |
||
| template< class T, class E > class expected; |
(1) | (C++23から) |
| template< class T, class E > requires std::is_void_v<T> |
(2) | (C++23から) |
クラステンプレート std::expected は、期待される値(T型)か、あるいは期待されない値(E型)かのいずれかを表す方法を提供します。expected が値を持たない状態になることはありません。
2)
void 部分特殊化。期待される void 値を表すか、期待されない値を保持します。期待されない値を保持する場合、その値は expected オブジェクトの内部にネストされます。参照型、関数型、または std::unexpected の特殊化で expected をインスタンス化するプログラムは不適格 (ill-formed) です。加えて、T は std::in_place_t や std::unexpect_t であってはなりません。
目次 |
[編集] テンプレートパラメータ
| T | - | 期待される値の型。型は (cv修飾された) void であるか、デストラクタ呼び出し可能 (Destructible) の要件を満たさなければなりません (特に、配列型や参照型は許可されません)。 |
| E | - | 期待されない値の型。型はデストラクタ呼び出し可能 (Destructible) の要件を満たし、std::unexpected の有効なテンプレート引数でなければなりません (特に、配列、非オブジェクト型、cv修飾された型は許可されません)。 |
[編集] メンバ型
| メンバ型 | 定義 |
value_type
|
T
|
error_type
|
E
|
unexpected_type
|
std::unexpected<E>
|
[編集] メンバエイリアステンプレート
| 型 | 定義 |
| rebind<U> | std::expected<U, error_type> |
[編集] データメンバ
| メンバ | 定義 |
bool has_val |
expected オブジェクトが現在、期待される値を表しているかどうか(説明用のメンバオブジェクト*) |
T val (プライマリテンプレートのみ) |
期待される値 (説明専用の variant メンバオブジェクト*) |
E unex |
期待されない値 (説明専用の variant メンバオブジェクト*) |
[編集] メンバ関数
expected オブジェクトを構築する(public member function) | |
expected オブジェクトと、それに含まれる値を破棄する(public member function) | |
| 内容を代入する (public member function) | |
監視 | |
| 期待される値にアクセスする (public member function) | |
| オブジェクトが期待される値を保持しているか確認する (public member function) | |
| 期待される値を返す (public member function) | |
| 期待されない値を返す (public member function) | |
| 期待される値が存在すればそれを返し、そうでなければ別の値を返す (public member function) | |
| 期待されない値が存在すればそれを返し、そうでなければ別の値を返す (public member function) | |
モナド操作 | |
期待される値が存在する場合、その値に対して与えられた関数を実行した結果を返し、そうでなければ expected 自体を返す(public member function) | |
期待される値が存在する場合、変換された期待される値を含む expected を返し、そうでなければ expected 自体を返す(public member function) | |
期待される値を保持している場合、expected 自体を返し、そうでなければ期待されない値に対して与えられた関数を実行した結果を返す(public member function) | |
期待される値を保持している場合、expected 自体を返し、そうでなければ変換された期待されない値を含む expected を返す(public member function) | |
変更 | |
| 期待される値を直接構築する (public member function) | |
| 内容を交換する (public member function) | |
[編集] 非メンバ関数
| (C++23) |
expected オブジェクトを比較する(function template) |
| (C++23) |
std::swap アルゴリズムを特殊化する (function) |
[編集] ヘルパークラス
| (C++23) |
期待されない値として表現される (class template) |
| (C++23) |
期待されない値を含む expected へのチェック付きアクセスを示す例外(class template) |
| (C++23) |
expected 内の期待されない値を直接構築するためのタグ(tag) |
[編集] 備考
同様の機能を持つ型は、RustではResult、HaskellではEitherと呼ばれています。
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_expected |
202202L |
(C++23) | クラステンプレート std::expected と関連するヘルパークラス |
202211L |
(C++23) | std::expected のためのモナディック関数 |
[編集] 例
このコードを実行
#include <cmath> #include <expected> #include <iomanip> #include <iostream> #include <string_view> enum class parse_error { invalid_input, overflow }; auto parse_number(std::string_view& str) -> std::expected<double, parse_error> { const char* begin = str.data(); char* end; double retval = std::strtod(begin, &end); if (begin == end) return std::unexpected(parse_error::invalid_input); else if (std::isinf(retval)) return std::unexpected(parse_error::overflow); str.remove_prefix(end - begin); return retval; } int main() { auto process = [](std::string_view str) { std::cout << "str: " << std::quoted(str) << ", "; if (const auto num = parse_number(str); num.has_value()) std::cout << "value: " << *num << '\n'; // If num did not have a value, dereferencing num // would cause an undefined behavior, and // num.value() would throw std::bad_expected_access. // num.value_or(123) uses specified default value 123. else if (num.error() == parse_error::invalid_input) std::cout << "error: invalid input\n"; else if (num.error() == parse_error::overflow) std::cout << "error: overflow\n"; else std::cout << "unexpected!\n"; // or invoke std::unreachable(); }; for (auto src : {"42", "42abc", "meow", "inf"}) process(src); }
出力
str: "42", value: 42 str: "42abc", value: 42 str: "meow", error: invalid input str: "inf", error: overflow
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 4141 | C++23 | ストレージの要件 紛らわしかった |
保持されるオブジェクトはexpected オブジェクトの内部にネストされる |
[編集] 参照
- C++23標準 (ISO/IEC 14882:2024)
- 22.8 Expected objects [expected]
[編集] 関連項目
| (C++17) |
型安全な判別共用体 (クラステンプレート) |
| (C++17) |
オブジェクトを保持しているかもしれないし、していないかもしれないラッパー (クラステンプレート) |