名稱空間
變體
操作

std::expected

來自 cppreference.com
< cpp‎ | 工具
 
 
 
 
定義於標頭檔案 <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 提供了一種表示兩種值之一的方式:一個型別為 T 的*預期*值,或一個型別為 E 的*非預期*值。expected 永遠不會是無值的。

1) 主模板。在其自身的儲存中包含預期值或非預期值,該儲存 巢狀在 expected 物件內。
2) void 偏特化。表示一個預期的 void 值或包含一個非預期值。如果它包含一個非預期值,則該值巢狀在 expected 物件內。

如果程式例項化了一個引用型別、函式型別或 std::unexpected 的特化的 expected,則程式格式錯誤。此外,T 不能是 std::in_place_tstd::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 物件
(公共成員函式) [編輯]
銷燬 expected 物件及其包含的值
(公共成員函式) [編輯]
賦值內容
(公共成員函式) [編輯]
觀察器
訪問預期值
(公共成員函式) [編輯]
檢查物件是否包含預期值
(公共成員函式) [編輯]
返回預期值
(公共成員函式) [編輯]
返回非預期值
(公共成員函式) [編輯]
如果存在,返回預期值;否則返回另一個值
(公共成員函式) [編輯]
如果存在,返回非預期值;否則返回另一個值
(公共成員函式) [編輯]
Monadic operations
如果預期值存在,返回給定函式作用於預期值的結果;否則返回 expected 自身
(公共成員函式) [編輯]
如果預期值存在,返回包含轉換後的預期值的 expected;否則返回 expected 自身
(公共成員函式) [編輯]
如果 expected 包含預期值,返回 expected 自身;否則返回給定函式作用於非預期值的結果
(公共成員函式) [編輯]
如果 expected 包含預期值,返回 expected 自身;否則返回包含轉換後的非預期值的 expected
(公共成員函式) [編輯]
修改器
就地構造預期值
(公共成員函式) [編輯]
交換內容
(公共成員函式) [編輯]

[編輯] 非成員函式

比較 expected 物件
(函式模板) [編輯]
特化 std::swap 演算法
(函式) [編輯]

[編輯] 輔助類

表示為意外值
(類模板) [編輯]
表示對包含非預期值的 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';
            // 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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 4141 C++23 儲存要求
令人困惑
包含的物件必須
巢狀在 expected 物件內

[編輯] 參考

  • C++23 標準 (ISO/IEC 14882:2024)
  • 22.8 預期物件 [expected]

[編輯] 另請參閱

(C++17)
一種型別安全的帶判別聯合體
(類模板) [編輯]
(C++17)
可能包含或不包含物件的包裝器
(類模板) [編輯]