C++23 adds some "monadic-style" functionality regarding optionals, as methods of optional<T>
:
optional<T>::and_then()
(and ignoring qualifiers of this
):
template<class F> constexpr auto and_then(F&& f);
Returns the result of invocation of f on the contained value if it exists. Otherwise, returns an empty value of the return type.
optional<T>::transform()
(and ignoring qualifiers of this
):
template<class F> constexpr auto transform(F&& f);
Returns an
std::optional
that contains the result of invocation off
on the contained value if*this
contains a value. Otherwise, returns an emptystd::optional
of such type.
So, aren't these two functions doing the same thing?
Suppose you have an optional<T1>
value.
transform()
lets you pass your optional to functions like T2 foo(T1 x)
;and_then()
lets you pass your optional to functions like optional<T2> bar(T1 x)
;... and get an optional<T2>
at the end. So, transform()
will "unbox", apply the function, then "re-box" the function's output into an optional, while and_then()
will not do the "re-boxing" at the end, expecting the function to return a boxed value on its own.
You might also think of transform
like std::transform
: You apply a function to "each element"; in a container, it may be any number of elements, and in an optional, it's either 0 or 1 elements.
See also this question.