Namespaces
Variants

std::optional<T>:: transform

From cppreference.net
Utilities library
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 であってはならない。そうでない場合、プログラムは不適格となる。

1) 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 ) ) ; が ill-formed である場合、プログラムは ill-formed となる。
2) (1) と同様だが、 U std:: remove_cv_t < std:: invoke_result_t < F, const T & >> である点が異なる。
3) U std:: remove_cv_t < std:: invoke_result_t < F, T >> と定義する。 * this が値を保持している場合、 std:: optional < U > を返す。この際、保持される値は std:: invoke ( std:: forward < F > ( f ) , std :: move ( ** this ) ) から直接初期化される。それ以外の場合、空の std:: optional < U > を返す。
変数定義 U x ( std:: invoke ( std:: forward < F > ( f ) , std :: move ( ** this ) ) ) ; が不適格な場合、プログラムは不適格となる。
4) (3) と同様、ただし U std:: remove_cv_t < std:: invoke_result_t < F, const T >> である。

目次

パラメータ

f - 適切な関数または Callable オブジェクトで、その呼び出しシグネチャが非参照型を返すもの

戻り値

f の結果を含む、または上記のように空の std::optional を返します。

注記

transform はコンストラクタに渡すのではなく、直接正しい位置に U オブジェクトを構築するため、 std:: is_move_constructible_v < U > false になる可能性があります。

呼び出し可能オブジェクト f が参照型を返すことができないため、これは データメンバへのポインタ にはなりえません。

一部の言語ではこの操作を map と呼びます。

機能テスト マクロ 標準 機能
__cpp_lib_optional 202110L (C++23) モナド操作 in 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

関連項目

利用可能な場合は含まれる値を返し、それ以外の場合は別の値を返す
(公開メンバ関数)
(C++23)
値が存在する場合は与えられた関数の結果を返し、それ以外の場合は空の optional を返す
(公開メンバ関数)
(C++23)
値が含まれている場合は optional 自体を返し、それ以外の場合は与えられた関数の結果を返す
(公開メンバ関数)