Talk:cpp/utility/optional/transform
From cppreference.com
[edit] Alternative transform
The member function seems needlessly constrained, so I thought it would be useful to show this version:
template<typename Optional, typename F> requires std::same_as<std::remove_cvref_t<Optional>, std::optional<typename std::remove_cvref_t<Optional>::value_type>> constexpr auto transform(Optional&& o, F&& f) -> std::optional<std::remove_cvref_t<decltype(std::invoke(std::forward<F>(f), std::forward<Optional>(o).value()))>> { if (!o) return {}; return {std::invoke(std::forward<F>(f), std::forward<Optional>(o).value())}; }
which is compatible with pointers to data member amongst other things (demo). --Ybab321 (talk) 09:44, 20 December 2021 (PST)
[edit] Difference of .transform() and .and_then()
It is hard to see the difference between optional<T>::transform() and optional<T>::and_then(), so it would be nice if the function description (or an example) would make it clear. --217.229.69.239 08:41, 21 March 2022 (PDT)
- The first sentence of the two pages has the difference: one "Returns an std::optional that contains the result of invocation of f ", other "Returns the result of invocation of f" and the Notes mention the equivalents in other languages (map and flatmap). But yes, idiomatic examples (showing idioms from Scala or another map/flatmap language) could be useful. --Cubbi (talk) 09:01, 21 March 2022 (PDT)
- Perhaps the example code is too complex. What would you think about this much simpler example:
// returns an empty optional, if v is empty // returns the size of the vector if v is non-empty std::optional<size_t> optional_size(const std::optional<std::vector>& opt_vec) { return opt_vec.transform(&std::size); // see https://en.cppreference.com/w/cpp/iterator/size }
- Can't be taking the address of stdlib functions as of C++20 [1], and even if you could, &std::size should fail because it won't know which overload to choose, need to make a lambda instead. I think I think Cubbi's example is good, it shows the chaining and usage with and without a stored value --Ybab321 (talk) 02:18, 22 March 2022 (PDT)
- I agree in the way that current example is too formal and could be replaced with something more practical.--Space Mission (talk) 03:03, 22 March 2022 (PDT)
- The way I see it, monadic operations are intended to work as a team - as in the example I threw together yesterday in cpp/utility/optional/and_then#Example: map (transform) applies a value-to-value function while skipping nulls, flatmap (and_then) applies a value-to-option function and unwraps (flattens) the options it returned, possibly creating new nulls: people who worked in e.g. Scala would instantly recognize them as such. Can always do both; begin an example with trivial use, and then combined use. --Cubbi (talk) 06:23, 22 March 2022 (PDT)
- I agree in the way that current example is too formal and could be replaced with something more practical.--Space Mission (talk) 03:03, 22 March 2022 (PDT)
- Can't be taking the address of stdlib functions as of C++20 [1], and even if you could, &std::size should fail because it won't know which overload to choose, need to make a lambda instead. I think I think Cubbi's example is good, it shows the chaining and usage with and without a stored value --Ybab321 (talk) 02:18, 22 March 2022 (PDT)