// optional<T>版のオーバーロード
template <class F> constexpr auto transform(F&& f) &; // (1) C++23
template <class F> constexpr auto transform(F&& f) &&; // (2) C++23
template <class F> constexpr auto transform(F&& f) const&; // (3) C++23
template <class F> constexpr auto transform(F&& f) const&&; // (4) C++23
// optional<T&>版のオーバーロード (C++26)
template <class F>
constexpr optional<invoke_result_t<F, T&>>
transform(F&& f) const; // (5) C++26
概要
有効値を保持していれば、値に対してfを適用した結果をoptionalに格納して返す。
有効値を保持していなければ、std::nulloptを返す。
- (1) :
*thisが非const左辺値の場合 - (2) :
*thisが非const右辺値の場合 - (3) :
*thisがconst左辺値の場合 - (4) :
*thisがconst右辺値の場合 - (5) :
optional<T&>の場合
optional<T>では (1)~(4) が定義され、optional<T&>では (5) のみが定義される。
実際には複数オーバーロードが提供されるが、大まかには下記シグニチャのようにみなせる。
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()))> - (5) :
remove_cv_t<invoke_result_t<F, decltype(*val)>>(説明専用メンバvalはT*型)
適格要件
- (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())));が妥当であること。
- (5) :
U型はoptionalに対する有効な要素型であること。- ある変数
uの宣言U u(invoke(std::forward<F>(f), *val));が妥当であること。
効果
- (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>()を返す。 - (5) :
*thisが有効値を保持するときは、invoke(std::forward<F>(f), *val)で直接非リスト初期化した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++: ??
関連項目
参照
- P0798R8 Monadic operations for std::optional
- P2988R12
std::optional<T&>- C++26で参照型
T&に対する部分特殊化を追加
- C++26で参照型