Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between C++23's optional::transform and optional::and_then?

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 of f on the contained value if *this contains a value. Otherwise, returns an empty std::optional of such type.

So, aren't these two functions doing the same thing?

like image 816
einpoklum Avatar asked Dec 06 '25 09:12

einpoklum


2 Answers

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.

like image 52
einpoklum Avatar answered Dec 08 '25 21:12

einpoklum


and_then only takes functions of type T -> std::optional<U> (whereas transform is free to take functions returning any type).

If you just transform with such a function you will get a std::optional<std::optional<U>>.

and_then just then flattens the std::optional<std::optional<U>> into an std::optional<U>.

That's all monads are: transform composed with a type level flatten. Think range<range<U>> and future<future<U>>.

like image 31
Tom Huntington Avatar answered Dec 08 '25 22:12

Tom Huntington



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!