最終更新日時: 2024年06月11日 22時45分38秒 (JST)
Akira Takahashi が更新

履歴 編集

function template
<expected>

# std::expected.void::transform(C++23)

    // expected<cv void, E>部分特殊化
    template<class F> constexpr auto transform(F&& f) &;        // (1)
    template<class F> constexpr auto transform(F&& f) const &;  // (2)
    template<class F> constexpr auto transform(F&& f) &&;       // (3)
    template<class F> constexpr auto transform(F&& f) const &&; // (4)

## 概要

正常値を保持していれば、`f`の呼び出し結果を`expected`の正常値として格納して返す。 エラー値を保持していれば、そのまま返す。

実際には複数オーバーロードが提供されるが、大まかには下記シグニチャのようにみなせる。 `transform`へは、引数をとらず`Return`型を返す関数や関数オブジェクトを与える。

    template <cv void, class E>
    class expected {
      template <class Return>
      std::expected<Return, E> transform(function<Return()> func);
    };

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

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

## 適格要件

- (1), (2) : 型`U`を`remove_cvref_t<invoke_result_t<F>>`としたとき、次を全て満たすこと
  - `U`が`expected`の有効な正常値型である
  - `U`が（CV修飾された）`void`ではないとき、宣言`U u(invoke(std::forward<F>(f)));`が妥当である
- (3), (4) : 型`U`を`remove_cvref_t<invoke_result_t<F>>`としたとき、次を全て満たすこと
  - `U`が`expected`の有効な正常値型である
  - `U`が（CV修飾された）`void`ではないとき、宣言`U u(invoke(std::forward<F>(f)));`が妥当である

## 効果

- (1), (2) : 次の効果をもつ
  - エラー値を保持していたら、`expected<U, E>(unexpect, error())`を返す。
  - 型`U`が（CV修飾された）`void`でなければ、正常値を`invoke(std::forward<F>(f))`で直接非リスト初期化した`expected<U, E>`オブジェクトを返す。
  - そうでなければ、`invoke(std::forward<F>(f))`を評価し、`expected<U, E>()`を返す。
- (3), (4) : 次の効果をもつ
  - エラー値を保持していたら、`expected<U, E>(unexpect, std::move(error()))`を返す。
  - 型`U`が（CV修飾された）`void`でなければ、正常値を`invoke(std::forward<F>(f))`で直接非リスト初期化した`expected<U, E>`オブジェクトを返す。
  - そうでなければ、`invoke(std::forward<F>(f))`を評価し、`expected<U, E>()`を返す。

## 備考

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

## 例

    #include <cassert>
    #include <expected>
    #include <string>

    int get_answer()
    {
      return 42;
    }

    int main()
    {
      std::expected<void, std::string> v1;
      assert(v1.transform(get_answer).value() == 42);

      std::expected<void, std::string> e1 = std::unexpected{"galaxy"};
      assert(e1.transform(get_answer).error() == "galaxy");
    }

### 出力

## バージョン

### 言語

- C++23

### 処理系

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

## 関連項目

- `and_then()`
- `or_else()`
- `transform_error()`

## 参照

- P2505R5 Monadic Functions for `std::expected`