Namespaces
Variants

std:: expected

From cppreference.net
Utilities library
ヘッダーで定義 <expected>
template < class T, class E >
class expected ;
(1) (C++23以降)
template < class T, class E >

requires std:: is_void_v < T >

class expected < T, E > ;
(2) (C++23以降)

クラステンプレート std::expected は、2つの値のいずれかを表現する方法を提供します: T 型の expected 値、または E 型の unexpected 値です。 expected は決して値を持たない状態にはなりません。

1) メインテンプレート。期待される値または期待されない値を自身のストレージ内に保持し、これは nested within the expected オブジェクト内に配置されます。
2) void の部分特殊化。期待される void 値を表すか、予期しない値を含む。予期しない値を含む場合、それは expected オブジェクト内にネストされる。

参照型、関数型、または std::unexpected の特殊化で expected をインスタンス化するプログラムは不適格です。さらに、 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 (メインテンプレートのみ) 期待値
( 説明専用バリアントメンバーオブジェクト* )
E unex 予期しない値
( 説明専用バリアントメンバーオブジェクト* )

メンバー関数

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 オブジェクトを比較する
(関数テンプレート)
std::swap アルゴリズムを特殊化する
(関数)

ヘルパークラス

(C++23)
予期しない値として表現される
(クラステンプレート)
予期しない値を含む expected へのチェック付きアクセスを示す例外
(クラステンプレート)
expected 内での予期しない値のインプレース構築タグ
(タグ)

注記

同じ機能を持つ型は、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';
            // numが値を持たない場合、numをデリファレンスすると
            // 未定義動作を引き起こし、num.value()は
            // std::bad_expected_accessをスローします。
            // num.value_or(123)は指定されたデフォルト値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"; // または 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 Applied to Behavior as published Correct behavior
LWG 4141 C++23 ストレージ要件が
混乱を招いていた
含まれるオブジェクトは
expected オブジェクト内に
ネストされなければならない

参考文献

  • C++23標準 (ISO/IEC 14882:2024):
  • 22.8 Expectedオブジェクト [expected]

関連項目

(C++17)
型安全な判別共用体
(クラステンプレート)
(C++17)
オブジェクトを保持する場合と保持しない場合があるラッパー
(クラステンプレート)