最終更新日時: 2026年01月06日 12時47分59秒 (JST)
Koichi Murase が更新

履歴 編集

function
<expected>

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

    constexpr void swap(expected& rhs) noexcept(see below);

## 概要

他の`expected`オブジェクトとデータを入れ替える。

動作説明用の`expected`クラスメンバ変数として、下記を導入する。

- `val` : `T`型の正常値。
- `unex` : `E`型のエラー値。
- `has_val` : `bool`型のフラグ変数。正常値を保持する場合は`true`に、エラー値を保持する場合は`false`となる。

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

次の制約を全て満たすこと

- `is_swappable_v<T> == true`
- `is_swappable_v<E> == true`
- `(is_move_constructible_v<T> && is_move_constructible_v<E>) == true`
- `(is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>) == true`

## 効果

`*this`と`rhs`それぞれが正常値／エラー値いずれを保持しているかに応じて、以下の効果を持つ。

- `*this`と`rhs`ともに正常値を保持していれば、次と等価 : `using std::swap; swap(val, rhs.val);`
- `*this`と`rhs`ともにエラー値を保持していれば、次と等価 : `using std::swap; swap(unex, rhs.unex);`
- `*this`がエラー値を`rhs`が正常値を保持していれば、次と等価 : `rhs.swap(*this);`
- `*this`が正常値を`rhs`がエラー値を保持していれば、次と等価 :

      if constexpr (is_nothrow_move_constructible_v<E>) {
        E tmp(std::move(rhs.unex));
        destroy_at(addressof(rhs.unex));
        try {
          construct_at(addressof(rhs.val), std::move(val));
          destroy_at(addressof(val));
          construct_at(addressof(unex), std::move(tmp));
        } catch(...) {
          construct_at(addressof(rhs.unex), std::move(tmp));
          throw;
        }
      } else {
        T tmp(std::move(val));
        destroy_at(addressof(val));
        try {
          construct_at(addressof(unex), std::move(rhs.unex));
          destroy_at(addressof(rhs.unex));
          construct_at(addressof(rhs.val), std::move(tmp));
        } catch (...) {
          construct_at(addressof(val), std::move(tmp));
          throw;
        }
      }
      has_val = false;
      rhs.has_val = true;

## 戻り値

なし

## 例外

noexcept例外指定は次の式に従う :

`is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>`

noexcept例外指定が`false`の場合、上記の「効果」による処理からの例外が送出される。

## 例

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

    int main()
    {
      std::expected<int, std::string> x = 42;
      std::expected<int, std::string> y = std::unexpected{"ERR"};
      assert(x.value() == 42 && y.error() == "ERR");

      x.swap(y);
      assert(x.error() == "ERR" && y.value() == 42);
    }

### 出力

## バージョン

### 言語

- C++23

### 処理系

- Clang: 16.0 ✅
- GCC: 12.1 ✅
- ICC: ??
- Visual C++: ??

## 参照

- P0323R12 std::expected