- expected[meta header]
- function template[meta id-type]
- std[meta namespace]
- expected[meta class]
- cpp23[meta cpp]
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);
};- function[link /reference/functional/function.md]
- (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());
- has_value()[link has_value.md]
- value()[link value.md]
- error()[link error.md]
- invoke[link /reference/functional/invoke.md]
-
(3), (4) : 次の処理と等価
if (has_value()) return G(in_place, std::move(value())); else return invoke(std::forward<F>(f), std::move(error()));
- has_value()[link has_value.md]
- value()[link value.md]
- error()[link error.md]
- invoke[link /reference/functional/invoke.md]
- std::move[link /reference/utility/move.md]
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");
}- or_else[color ff0000]
- value()[link value.md]
- error()[link error.md]
- std::unexpected[link ../unexpected.md]
- std::from_chars[link /reference/charconv/from_chars.md]
- std::errc[link /reference/system_error/errc.md]
- C++23
- Clang: ??
- GCC: 13.0 [mark verified]
- ICC: ??
- Visual C++: ??