GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • cpprefjp - C++日本語リファレンス
  • GitHub Project

This view

  • Original page
  • New address

GeezerVison is showing cpprefjp.github.io — std::optional::or_else - cpprefjp C++日本語リファレンス

  1. リファレンス
  2. optional
  3. optional
  4. or_else

最終更新日時: 2026年09月19日 21時31分51秒 (JST)
rotarymars が更新

履歴 編集

function template
<optional>

std::optional::or_else(C++23)

// optional<T>版のオーバーロード
template<class F> constexpr optional or_else(F&& f) const &; // (1) C++23
template<class F> constexpr optional or_else(F&& f) &&;      // (2) C++23

// optional<T&>版のオーバーロード (C++26)
template<class F> constexpr optional or_else(F&& f) const;   // (3) C++26

概要

有効値を保持していれば、なにもしない。 有効値を保持していなければ、f()の呼び出し結果をoptionalとして返す。

  • (1) : *thisがconst左辺値の場合
  • (2) : *thisが右辺値の場合
  • (3) : optional<T&>の場合

optional<T>では (1), (2) が定義され、optional<T&>では (3) のみが定義される。

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

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

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

  • (1) : Fはinvocable<>のモデル、かつTはcopy_constructibleのモデルであること
  • (2) : Fはinvocable<>のモデル、かつTはmove_constructibleのモデルであること
  • (3) : Fはinvocable<>のモデル、かつTはcopy_constructibleのモデルであること

適格要件

is_same_v<remove_cvref_t<invoke_result_t<F>>, optional>がtrueであること

効果

  • (1), (3) : 次と等価

    if (*this) {
      return *this;
    } else {
      return std::forward<F>(f)();
    }
    

  • (2) : 次と等価

    if (*this) {
      return std::move(*this);
    } else {
      return std::forward<F>(f)();
    }
    

備考

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

例

基本的な使い方

#include <cassert>
#include <optional>

std::optional<int> defvalue()
{
  return 42;
}

int main()
{
  std::optional<int> o1 = 1;
  assert(o1.or_else(defvalue).value() == 1);

  std::optional<int> o2 = std::nullopt;
  assert(o2.or_else(defvalue).value() == 42);
}

出力

メソッドチェインとしての使い方

#include <cassert>
#include <charconv>
#include <optional>
#include <string_view>

std::optional<int> parse(std::string_view sv, int base, std::string_view prefix = "")
{
  if (!prefix.empty() && !sv.starts_with(prefix))
    return std::nullopt;
  int n{};
  auto [ptr, ec] = std::from_chars(sv.data() + prefix.size(), sv.data() + sv.size(), n, base);
  if (ec == std::errc{} && ptr == sv.data() + sv.size())
    return n;
  else
    return std::nullopt;
}

std::optional<int> parse_digit(std::string_view sv)
{
  return parse(sv, 2, "0b")
    .or_else([sv] { return parse(sv, 10); })
    .or_else([sv] { return parse(sv, 16, "0x"); });
}

int main()
{
  assert(parse_digit("0b11") == std::optional(3));
  assert(parse_digit("11") == std::optional(11));
  assert(parse_digit("0x11") == std::optional(17));
  assert(parse_digit("x") == std::nullopt);
}

出力

バージョン

言語

  • C++23

処理系

  • Clang: 14.0.6 ✅
  • GCC: ??
  • Visual C++: ??

関連項目

  • and_then
  • transform
  • value_or

参照

  • P0798R8 Monadic operations for std::optional
  • P2988R12 std::optional<T&>
    • C++26で参照型T&に対する部分特殊化を追加
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.