- expected[meta header]
- function template[meta id-type]
- std[meta namespace]
- expected.void[meta class]
- cpp23[meta cpp]
// expected<cv void, E>部分特殊化
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
へは、引数をとらずstd::expected<Return, E>
型を返す関数や関数オブジェクトを与える。
template <cv void, class E>
class expected {
template <class Return>
std::expected<Return, E> and_then(function<std::expected<Return, E>()> func);
};
- function[link /reference/functional/function.md]
- (1), (2) :
is_copy_constructible_v
<E> == true
- (3), (4) :
is_move_constructible_v
<E> == true
- (1), (2) : 型
U
をremove_cvref_t
<
invoke_result_t
<F>>
としたとき、次を全て満たすことU
がexpected
の特殊化であるis_same_v
<U::error_type, E> == true
- (3), (4) : 型
U
をremove_cvref_t
<
invoke_result_t
<F>>
としたとき、次を全て満たすことU
がexpected
の特殊化であるis_same_v
<U::error_type, E> == true
-
(1), (2) : 次の処理と等価
if (has_value()) return invoke(std::forward<F>(f)); else return U(unexpect, error());
- has_value[link has_value.md]
- error()[link error.md]
- unexpect[link ../unexpect_t.md]
- invoke[link /reference/functional/invoke.md]
- std::forward[link /reference/utility/forward.md]
-
(3), (4) : 次の処理と等価
if (has_value()) return invoke(std::forward<F>(f)); else return U(unexpect, std::move(error()));
- has_value[link has_value.md]
- error()[link error.md]
- unexpect[link ../unexpect_t.md]
- invoke[link /reference/functional/invoke.md]
- std::forward[link /reference/utility/forward.md]
- std::move[link /reference/utility/move.md]
and_then
は、メソッドチェーンをサポートするモナド風(monadic)操作として導入された。
#include <cassert>
#include <expected>
#include <string>
std::expected<void, std::string> ok()
{
return {};
}
std::expected<void, std::string> ng()
{
return std::unexpected{"ng"};
}
int main()
{
std::expected<void, std::string> v1;
assert(v1.and_then(ok).has_value());
std::expected<void, std::string> v2;
assert(v2.and_then(ng).error() == "ng");
std::expected<void, std::string> e1 = std::unexpected{"empty"};
assert(e1.and_then(ng).error() == "empty");
}
- and_then[color ff0000]
- has_value()[link has_value.md]
- error()[link error.md]
- std::unexpected[link ../unexpected.md]
- C++23
- Clang: ??
- GCC: 13.0 [mark verified]
- ICC: ??
- Visual C++: ??