std::optional<T>::transform
From cppreference.com
| template< class F > constexpr auto transform( F&& f ) &; |
(1) | (C++23から) |
| template< class F > constexpr auto transform( F&& f ) const&; |
(2) | (C++23から) |
| template< class F > constexpr auto transform( F&& f ) &&; |
(3) | (C++23から) |
| template< class F > constexpr auto transform( F&& f ) const&&; |
(4) | (C++23から) |
*this が値を保持している場合、保持されている値を引数として f を呼び出し、その呼び出しの結果を保持する std::optional を返します。それ以外の場合は、空の std::optional を返します。
結果に含まれる値の型(以下 U で示されます)は、非配列オブジェクト型でなければならず、std::in_place_t または std::nullopt_t であってはなりません。それ以外の場合、プログラムは不適格(ill-formed)です。
1)
変数定義 U x(std::invoke(std::forward<F>(f), **this)); が不適格な場合、プログラムは不適格です。
U を std::remove_cv_t<std::invoke_result_t<F, T&>> とします。*this が値を保持している場合、その保持されている値が 直接初期化 された std::optional<U> を返します。その値は std::invoke(std::forward<F>(f), **this) です(and_then() とは異なり、直接 std::optional を返す必要があります)。それ以外の場合、空の std::optional<U> を返します。変数定義 U x(std::invoke(std::forward<F>(f), **this)); が不適格な場合、プログラムは不適格です。
3)
変数定義 U x(std::invoke(std::forward<F>(f), std::move(**this))); が不適格な場合、プログラムは不適格です。
U を std::remove_cv_t<std::invoke_result_t<F, T>> とします。*this が値を保持している場合、その保持されている値が std::invoke(std::forward<F>(f), std::move(**this)) によって直接初期化された std::optional<U> を返します。それ以外の場合、空の std::optional<U> を返します。変数定義 U x(std::invoke(std::forward<F>(f), std::move(**this))); が不適格な場合、プログラムは不適格です。
目次 |
[編集] パラメータ
| f | - | 非参照型の値を返す、適切な関数または Callable オブジェクト |
[編集] 戻り値
f の結果を保持する std::optional、または前述の通り空の std::optional。
[編集] 注釈
transform は、コンストラクタに渡すのではなく、U オブジェクトを直接適切な場所に構築するため、std::is_move_constructible_v<U> が false である可能性があります。
呼び出し可能な f は参照型を返すことができないため、データメンバへのポインタではありません。
一部の言語では、この操作を map と呼びます。
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_optional |
202110L |
(C++23) | std::optional におけるモナド操作 |
[編集] 例
このコードを実行
#include <iostream> #include <optional> struct A { /* ... */ }; struct B { /* ... */ }; struct C { /* ... */ }; struct D { /* ... */ }; auto A_to_B(A) -> B { /* ... */ std::cout << "A => B \n"; return {}; } auto B_to_C(B) -> C { /* ... */ std::cout << "B => C \n"; return {}; } auto C_to_D(C) -> D { /* ... */ std::cout << "C => D \n"; return {}; } void try_transform_A_to_D(std::optional<A> o_A) { std::cout << (o_A ? "o_A has a value\n" : "o_A is empty\n"); std::optional<D> o_D = o_A.transform(A_to_B) .transform(B_to_C) .transform(C_to_D); std::cout << (o_D ? "o_D has a value\n\n" : "o_D is empty\n\n"); }; int main() { try_transform_A_to_D( A{} ); try_transform_A_to_D( {} ); }
出力
o_A has a value A => B B => C C => D o_D has a value o_A is empty o_D is empty
[編集] 関連項目
| 保持されている値が利用可能であればそれを返し、そうでなければ別の値を返す (public member function) | |
| (C++23) |
保持されている値が存在する場合、その値に対して与えられた関数の結果を返し、そうでなければ空の optional を返す(public member function) |
| (C++23) |
値を保持している場合は optional 自身を返し、そうでなければ与えられた関数の結果を返す(public member function) |