template <class F> constexpr auto and_then(F&& f) &; // (1)
template <class F> constexpr auto and_then(F&& f) &&; // (2)
template <class F> constexpr auto and_then(F&& f) const&; // (3)
template <class F> constexpr auto and_then(F&& f) const&&; // (4)
概要
有効値を保持していれば、値に対してf
を適用した結果をoptional
として返す。
有効値を保持していなければ、std::nullopt
を返す。
実際には複数オーバーロードが提供されるが、大まかには下記シグニチャのようにみなせる。
and_then
へは、引数リストに1個のT
型をとりstd::optional<Return>
型を返す関数や関数オブジェクトを与える。
template <class T>
class optional {
template <class Return>
std::optional<Return> and_then(function<std::optional<Return>(T)> func);
};
適格要件
説明用のU
型を次の通りとする:
- (1), (3) :
invoke_result_t<F, decltype(value())>
- (2), (4) :
invoke_result_t<F, decltype(std::move(value()))>
remove_cvref_t<U>
はoptional
の特殊化であること
効果
-
(1), (3) : 次と等価
if (*this) { return invoke(std::forward<F>(f), value()); } else { return remove_cvref_t<U>(); }
-
(2), (4) : 次と等価
if (*this) { return invoke(std::forward<F>(f), std::move(value())); } else { return remove_cvref_t<U>(); }
備考
and_then
は、メソッドチェーンをサポートするモナド風(monadic)操作として導入された。
関数型プログラミングの文脈における Monadic Bind 操作に対応する。
例
#include <cassert>
#include <optional>
// 正数なら2倍/それ以外は無効値を返す関数
std::optional<int> twice(int n)
{
if (0 < n) {
return n * 2;
} else {
return std::nullopt;
}
}
int main()
{
std::optional<int> o1 = 2;
assert(o1.and_then(twice).value() == 4);
std::optional<int> o2 = -1;
assert(not o2.and_then(twice).has_value());
std::optional<int> o3 = std::nullopt;
assert(not o3.and_then(twice).has_value());
}
出力
バージョン
言語
- C++23
処理系
- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??