最終更新日時(UTC): 2025年07月08日 15時33分39秒
Akira Takahashi が更新

履歴 編集

function template
<expected>

# std::expected::or_else(C++23)

    template<class F> constexpr auto or_else(F&& f) &;        // (1)
    template<class F> constexpr auto or_else(F&& f) const &;  // (2)
    template<class F> constexpr auto or_else(F&& f) &&;       // (3)
    template<class F> constexpr auto or_else(F&& f) const &&; // (4)

## 概要

エラー値を保持していれば、エラー値に対して`f`を適用した結果を`expected`として返す。 正常値を保持していれば、そのまま返す。

実際には複数オーバーロードが提供されるが、大まかには下記シグニチャのようにみなせる。 `or_else`へは、引数リストに1個の`E`型をとり`std::expected<T, Return>`型を返す関数や関数オブジェクトを与える。

    template <class T, class E>
    class expected {
      template <class Return>
      std::expected<T, Return> or_else(function<std::expected<T, Return>(E)> func);
    };

## テンプレートパラメータ制約

- (1), (2) : `is_copy_constructible_v<T> == true`
- (3), (4) : `is_move_constructible_v<T> == true`

## 適格要件

- (1), (2) : 型`G`を`remove_cvref_t<invoke_result_t<F, decltype(error())>>`としたとき、次を全て満たすこと
  - `G`が`expected`の特殊化である
  - `is_same_v<G::value_type, T> == true`
- (3), (4) : 型`G`を`remove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>`としたとき、次を全て満たすこと
  - `G`が`expected`の特殊化である
  - `is_same_v<G::value_type, T> == true`

## 効果

- (1), (2) : 次の処理と等価

      if (has_value())
        return G(in_place, value());
      else
        return invoke(std::forward<F>(f), error());

- (3), (4) : 次の処理と等価

      if (has_value())
        return G(in_place, std::move(value()));
      else
        return invoke(std::forward<F>(f), std::move(error()));

## 備考

`or_else`は、メソッドチェーンをサポートするモナド風(monadic)操作として導入された。

## 例

    #include <cassert>
    #include <charconv>
    #include <expected>
    #include <string>
    #include <string_view>

    // 文字列を正常値(数値)として再解釈する関数
    std::expected<int, std::string> parse(std::string_view s)
    {
      int val{};
      auto [ptr, ec] = std::from_chars(s.begin(), s.end(), val);
      if (ec == std::errc{} && ptr == s.end()) {
        return val;
      } else {
        return std::unexpected<std::string>{s};
      }
    }

    int main()
    {
      std::expected<int, std::string> v1 = 1;
      assert(v1.or_else(parse).value() == 1);

      std::expected<int, std::string> e1 = std::unexpected{"123"};
      assert(e1.or_else(parse) == 123);

      std::expected<int, std::string> e2 = std::unexpected{"bad"};
      assert(e2.or_else(parse).error() == "bad");
    }

### 出力

## バージョン

### 言語

- C++23

### 処理系

- Clang: ??
- GCC: 13.0 ✅
- ICC: ??
- Visual C++: ??

## 関連項目

- `and_then()`
- `transform()`
- `transform_error()`

## 参照

- P2505R5 Monadic Functions for `std::expected`