template<class F> constexpr auto and_then(F&& f) &; // (1)
template<class F> constexpr auto and_then(F&& f) const &; // (2)
template<class F> constexpr auto and_then(F&& f) &&; // (3)
template<class F> constexpr auto and_then(F&& f) const &&; // (4)
概要
正常値を保持していれば、正常値に対してfを適用した結果をexpectedとして返す。
エラー値を保持していれば、そのまま返す。
実際には複数オーバーロードが提供されるが、大まかには下記シグニチャのようにみなせる。
and_thenへは、引数リストに1個のT型をとりstd::expected<Return, E>型を返す関数や関数オブジェクトを与える。
template <class T, class E>
class expected {
template <class Return>
std::expected<Return, E> and_then(function<std::expected<Return, E>(T)> func);
};
テンプレートパラメータ制約
- (1), (2) :
is_constructible_v<E, decltype(error())> == true - (3), (4) :
is_constructible_v<E, decltype(std::move(error()))> == true
適格要件
- (1), (2) : 型
Uをremove_cvref_t<invoke_result_t<F, decltype(**this)>>としたとき、次を全て満たすことUがexpectedの特殊化であるis_same_v<U::error_type, E> == true
- (3), (4) : 型
Uをremove_cvref_t<invoke_result_t<F, decltype(std::move(**this))>>としたとき、次を全て満たすことUがexpectedの特殊化であるis_same_v<U::error_type, E> == true
効果
-
(1), (2) : 次の処理と等価
-
(3), (4) : 次の処理と等価
備考
and_thenは、メソッドチェーンをサポートするモナド風(monadic)操作として導入された。
例
#include <cassert>
#include <expected>
#include <string>
// 正数なら2倍/それ以外はエラー値を返す関数
std::expected<int, std::string> twice(int n)
{
if (0 < n) {
return n * 2;
} else {
return std::unexpected{"out of domain"};
}
}
int main()
{
std::expected<int, std::string> v1 = 1;
assert(v1.and_then(twice).value() == 2);
std::expected<int, std::string> v2 = 0;
assert(v2.and_then(twice).error() == "out of domain");
std::expected<int, std::string> e1 = std::unexpected{"NaN"};
assert(e1.and_then(twice).error() == "NaN");
}
出力
バージョン
言語
- C++23
処理系
- Clang: ??
- GCC: 13.0 ✅
- ICC: ??
- Visual C++: ??
関連項目
参照
- P2505R5 Monadic Functions for
std::expected - LWG Issue 3877. Incorrect constraints on
const-qualified monadic overloads forstd::expected- C++23で、
const修飾版で誤ってエラーになる問題を解消するため、制約がis_copy_constructible_v<E>からis_constructible_v<E, decltype(error())>(右辺値版はdecltype(std::move(error())))へ変更された
- C++23で、
- LWG Issue 3938. Cannot use
std::expectedmonadic ops with move-onlyerror_type