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